| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index aeb798833557a3b06b90ade0ce623bd83e8a7ac1..5386ffb9a11f03368143ae8196ad8c487e2c5de6 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -95,6 +95,7 @@ Instance* Object::null_instance_ = NULL;
|
| TypeArguments* Object::null_type_arguments_ = NULL;
|
| Array* Object::empty_array_ = NULL;
|
| Array* Object::zero_array_ = NULL;
|
| +ObjectPool* Object::empty_object_pool_ = NULL;
|
| PcDescriptors* Object::empty_descriptors_ = NULL;
|
| LocalVarDescriptors* Object::empty_var_descriptors_ = NULL;
|
| ExceptionHandlers* Object::empty_exception_handlers_ = NULL;
|
| @@ -132,6 +133,7 @@ RawClass* Object::script_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::library_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| +RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| @@ -403,6 +405,7 @@ void Object::InitOnce(Isolate* isolate) {
|
| null_type_arguments_ = TypeArguments::ReadOnlyHandle();
|
| empty_array_ = Array::ReadOnlyHandle();
|
| zero_array_ = Array::ReadOnlyHandle();
|
| + empty_object_pool_ = ObjectPool::ReadOnlyHandle();
|
| empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
|
| empty_var_descriptors_ = LocalVarDescriptors::ReadOnlyHandle();
|
| empty_exception_handlers_ = ExceptionHandlers::ReadOnlyHandle();
|
| @@ -541,6 +544,9 @@ void Object::InitOnce(Isolate* isolate) {
|
| cls = Class::New<Code>();
|
| code_class_ = cls.raw();
|
|
|
| + cls = Class::New<ObjectPool>();
|
| + object_pool_class_ = cls.raw();
|
| +
|
| cls = Class::New<Instructions>();
|
| instructions_class_ = cls.raw();
|
|
|
| @@ -625,6 +631,22 @@ void Object::InitOnce(Isolate* isolate) {
|
| zero_array_->SetAt(0, smi);
|
| }
|
|
|
| + // Allocate and initialize the canonical empty object pool object.
|
| + {
|
| + uword address =
|
| + heap->Allocate(ObjectPool::InstanceSize(0), Heap::kOld);
|
| + InitializeObject(address,
|
| + kObjectPoolCid,
|
| + ObjectPool::InstanceSize(0));
|
| + ObjectPool::initializeHandle(
|
| + empty_object_pool_,
|
| + reinterpret_cast<RawObjectPool*>(address + kHeapObjectTag));
|
| + empty_object_pool_->StoreNonPointer(
|
| + &empty_object_pool_->raw_ptr()->length_, 0);
|
| + empty_object_pool_->StoreNonPointer(
|
| + &empty_object_pool_->raw_ptr()->num_tagged_entries_, 0);
|
| + }
|
| +
|
| // Allocate and initialize the empty_descriptors instance.
|
| {
|
| uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
|
| @@ -810,6 +832,7 @@ void Object::FinalizeVMIsolate(Isolate* isolate) {
|
| SET_CLASS_NAME(library, LibraryClass);
|
| SET_CLASS_NAME(namespace, Namespace);
|
| SET_CLASS_NAME(code, Code);
|
| + SET_CLASS_NAME(object_pool, ObjectPool);
|
| SET_CLASS_NAME(instructions, Instructions);
|
| SET_CLASS_NAME(pc_descriptors, PcDescriptors);
|
| SET_CLASS_NAME(stackmap, Stackmap);
|
| @@ -3213,6 +3236,8 @@ RawString* Class::GenerateUserVisibleName() const {
|
| return Symbols::Namespace().raw();
|
| case kCodeCid:
|
| return Symbols::Code().raw();
|
| + case kObjectPoolCid:
|
| + return Symbols::ObjectPool().raw();
|
| case kInstructionsCid:
|
| return Symbols::Instructions().raw();
|
| case kPcDescriptorsCid:
|
| @@ -10512,6 +10537,53 @@ Class& cls = Class::Handle();
|
| #endif // defined(DART_NO_SNAPSHOT).
|
|
|
|
|
| +RawObjectPool* ObjectPool::New(intptr_t len, intptr_t num_tagged_entries) {
|
| + ASSERT(Object::object_pool_class() != Class::null());
|
| + ASSERT(num_tagged_entries <= len);
|
| + if (len < 0 || len > kMaxElements) {
|
| + // This should be caught before we reach here.
|
| + FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len);
|
| + }
|
| + ObjectPool& result = ObjectPool::Handle();
|
| + {
|
| + uword size = ObjectPool::InstanceSize(len);
|
| + RawObject* raw = Object::Allocate(ObjectPool::kClassId,
|
| + size,
|
| + Heap::kOld);
|
| + NoSafepointScope no_safepoint;
|
| + result ^= raw;
|
| + result.SetLength(len);
|
| + result.SetNumTaggedEntries(num_tagged_entries);
|
| + }
|
| + return result.raw();
|
| +}
|
| +
|
| +
|
| +const char* ObjectPool::ToCString() const {
|
| + return "ObjectPool";
|
| +}
|
| +
|
| +
|
| +void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
| + Object::PrintJSONImpl(stream, ref);
|
| +}
|
| +
|
| +
|
| +void ObjectPool::DebugPrint() const {
|
| + ISL_Print("Object Pool: {\n");
|
| + for (intptr_t i = 0; i < Length(); i++) {
|
| + if (i < NumTaggedEntries()) {
|
| + ISL_Print(" %" Pd ": 0x%" Px " %s\n", i,
|
| + reinterpret_cast<uword>(ObjectAt(i)),
|
| + Object::Handle(ObjectAt(i)).ToCString());
|
| + } else {
|
| + ISL_Print(" %" Pd ": 0x%" Px "\n", i, RawValueAt(i));
|
| + }
|
| + }
|
| + ISL_Print("}\n");
|
| +}
|
| +
|
| +
|
| RawInstructions* Instructions::New(intptr_t size) {
|
| ASSERT(Object::instructions_class() != Class::null());
|
| if (size < 0 || size > kMaxElements) {
|
| @@ -12313,6 +12385,8 @@ RawCode* Code::FinalizeCode(const char* name,
|
| Assembler* assembler,
|
| bool optimized) {
|
| ASSERT(assembler != NULL);
|
| + const ObjectPool& object_pool =
|
| + ObjectPool::Handle(assembler->object_pool().MakeObjectPool());
|
|
|
| // Allocate the Code and Instructions objects. Code is allocated first
|
| // because a GC during allocation of the code will leave the instruction
|
| @@ -12363,17 +12437,10 @@ RawCode* Code::FinalizeCode(const char* name,
|
| code.set_is_alive(true);
|
|
|
| // Set object pool in Instructions object.
|
| - const GrowableObjectArray& object_pool = assembler->object_pool_data();
|
| - if (object_pool.IsNull()) {
|
| - instrs.set_object_pool(Object::empty_array().raw());
|
| - } else {
|
| - INC_STAT(Isolate::Current(),
|
| - total_code_size, object_pool.Length() * sizeof(uintptr_t));
|
| - // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here
|
| - // with Heap::kOld and change the ARM and MIPS assemblers to work with a
|
| - // GrowableObjectArray in new space.
|
| - instrs.set_object_pool(Array::MakeArray(object_pool));
|
| - }
|
| + INC_STAT(Isolate::Current(),
|
| + total_code_size, object_pool.Length() * sizeof(uintptr_t));
|
| + instrs.set_object_pool(object_pool.raw());
|
| +
|
| if (FLAG_write_protect_code) {
|
| uword address = RawObject::ToAddr(instrs.raw());
|
| bool status = VirtualMemory::Protect(
|
| @@ -12600,8 +12667,8 @@ void Code::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
| jsobj.AddPropertyF("_startAddress", "%" Px "", EntryPoint());
|
| jsobj.AddPropertyF("_endAddress", "%" Px "", EntryPoint() + Size());
|
| jsobj.AddProperty("_alive", is_alive());
|
| - const Array& array = Array::Handle(ObjectPool());
|
| - jsobj.AddProperty("_objectPool", array);
|
| + const ObjectPool& object_pool = ObjectPool::Handle(GetObjectPool());
|
| + jsobj.AddProperty("_objectPool", object_pool);
|
| {
|
| JSONArray jsarr(&jsobj, "_disassembly");
|
| if (is_alive()) {
|
|
|