Optimize LocalVarDescriptor objects for functions that have no local variables
Allocate a canonical “empty” variable descriptor object. Saves about 10% of variable descriptor space when running dart2js. R=asiva@google.com Review URL: https://codereview.chromium.org//565513002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@40158 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -98,6 +98,7 @@ TypeArguments* Object::null_type_arguments_ = NULL;
|
||||
Array* Object::empty_array_ = NULL;
|
||||
Array* Object::zero_array_ = NULL;
|
||||
PcDescriptors* Object::empty_descriptors_ = NULL;
|
||||
LocalVarDescriptors* Object::empty_var_descriptors_ = NULL;
|
||||
Instance* Object::sentinel_ = NULL;
|
||||
Instance* Object::transition_sentinel_ = NULL;
|
||||
Instance* Object::unknown_constant_ = NULL;
|
||||
@@ -435,6 +436,7 @@ void Object::InitOnce() {
|
||||
empty_array_ = Array::ReadOnlyHandle();
|
||||
zero_array_ = Array::ReadOnlyHandle();
|
||||
empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
|
||||
empty_var_descriptors_ = LocalVarDescriptors::ReadOnlyHandle();
|
||||
sentinel_ = Instance::ReadOnlyHandle();
|
||||
transition_sentinel_ = Instance::ReadOnlyHandle();
|
||||
unknown_constant_ = Instance::ReadOnlyHandle();
|
||||
@@ -665,6 +667,20 @@ void Object::InitOnce() {
|
||||
empty_descriptors_->raw_ptr()->length_ = 0;
|
||||
}
|
||||
|
||||
// Allocate and initialize the canonical empty variable descriptor object.
|
||||
{
|
||||
uword address = heap->Allocate(
|
||||
LocalVarDescriptors::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address, kLocalVarDescriptorsCid,
|
||||
LocalVarDescriptors::InstanceSize(0));
|
||||
LocalVarDescriptors::initializeHandle(
|
||||
empty_var_descriptors_,
|
||||
reinterpret_cast<RawLocalVarDescriptors*>(address + kHeapObjectTag));
|
||||
empty_var_descriptors_->raw_ptr()->length_ = 0;
|
||||
// Can't use instance mentod StorePointer() here, but this pointer
|
||||
// assignment is safe (from old space to old space).
|
||||
empty_var_descriptors_->raw_ptr()->names_ = empty_array_->raw_ptr();
|
||||
}
|
||||
|
||||
cls = Class::New<Instance>(kDynamicCid);
|
||||
cls.set_is_abstract();
|
||||
|
||||
@@ -393,6 +393,11 @@ class Object {
|
||||
return *empty_descriptors_;
|
||||
}
|
||||
|
||||
static const LocalVarDescriptors& empty_var_descriptors() {
|
||||
ASSERT(empty_var_descriptors_ != NULL);
|
||||
return *empty_var_descriptors_;
|
||||
}
|
||||
|
||||
// The sentinel is a value that cannot be produced by Dart code.
|
||||
// It can be used to mark special values, for example to distinguish
|
||||
// "uninitialized" fields.
|
||||
@@ -670,6 +675,7 @@ class Object {
|
||||
static Array* empty_array_;
|
||||
static Array* zero_array_;
|
||||
static PcDescriptors* empty_descriptors_;
|
||||
static LocalVarDescriptors* empty_var_descriptors_;
|
||||
static Instance* sentinel_;
|
||||
static Instance* transition_sentinel_;
|
||||
static Instance* unknown_constant_;
|
||||
@@ -3099,6 +3105,7 @@ class LocalVarDescriptors : public Object {
|
||||
private:
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(LocalVarDescriptors, Object);
|
||||
friend class Class;
|
||||
friend class Object;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1102,6 +1102,8 @@ class RawLocalVarDescriptors : public RawObject {
|
||||
|
||||
// Variable info with [length_] entries.
|
||||
VarInfo* data() { OPEN_ARRAY_START(VarInfo, int32_t); }
|
||||
|
||||
friend class Object;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -266,6 +266,9 @@ RawLocalVarDescriptors* LocalScope::GetVarDescriptors(const Function& func) {
|
||||
int16_t scope_id = 0;
|
||||
CollectLocalVariables(&vars, &scope_id);
|
||||
|
||||
if (vars.length() == 0) {
|
||||
return Object::empty_var_descriptors().raw();
|
||||
}
|
||||
const LocalVarDescriptors& var_desc =
|
||||
LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length()));
|
||||
for (int i = 0; i < vars.length(); i++) {
|
||||
@@ -294,7 +297,7 @@ void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars,
|
||||
// This is the outermost scope with a context level or this scope's
|
||||
// context level differs from its parent's level.
|
||||
VarDesc desc;
|
||||
desc.name = &String::Handle(); // No name.
|
||||
desc.name = &Object::null_string(); // No name.
|
||||
desc.info.set_kind(RawLocalVarDescriptors::kContextLevel);
|
||||
desc.info.scope_id = *scope_id;
|
||||
desc.info.begin_pos = begin_token_pos();
|
||||
|
||||
Reference in New Issue
Block a user