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:
hausner@google.com
2014-09-11 16:08:59 +00:00
parent 05f69a65e0
commit 2f2cedfa42
4 changed files with 29 additions and 1 deletions
+16
View File
@@ -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();
+7
View File
@@ -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;
};
+2
View File
@@ -1102,6 +1102,8 @@ class RawLocalVarDescriptors : public RawObject {
// Variable info with [length_] entries.
VarInfo* data() { OPEN_ARRAY_START(VarInfo, int32_t); }
friend class Object;
};
+4 -1
View File
@@ -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();