OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 2152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 void AttachCode(const Code& value) const; | 2163 void AttachCode(const Code& value) const; |
2164 void SetInstructions(const Code& value) const; | 2164 void SetInstructions(const Code& value) const; |
2165 void ClearCode() const; | 2165 void ClearCode() const; |
2166 | 2166 |
2167 // Disables optimized code and switches to unoptimized code. | 2167 // Disables optimized code and switches to unoptimized code. |
2168 void SwitchToUnoptimizedCode() const; | 2168 void SwitchToUnoptimizedCode() const; |
2169 | 2169 |
2170 // Return the most recently compiled and installed code for this function. | 2170 // Return the most recently compiled and installed code for this function. |
2171 // It is not the only Code object that points to this function. | 2171 // It is not the only Code object that points to this function. |
2172 RawCode* CurrentCode() const { | 2172 RawCode* CurrentCode() const { |
2173 return raw_ptr()->code_; | 2173 return raw_ptr()->instructions_->ptr()->code_; |
2174 } | 2174 } |
2175 | 2175 |
2176 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } | 2176 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } |
2177 void set_unoptimized_code(const Code& value) const; | 2177 void set_unoptimized_code(const Code& value) const; |
2178 bool HasCode() const; | 2178 bool HasCode() const; |
2179 | 2179 |
2180 static intptr_t code_offset() { | |
2181 return OFFSET_OF(RawFunction, code_); | |
2182 } | |
2183 | |
2184 static intptr_t entry_point_offset() { | 2180 static intptr_t entry_point_offset() { |
2185 return OFFSET_OF(RawFunction, entry_point_); | 2181 return OFFSET_OF(RawFunction, entry_point_); |
2186 } | 2182 } |
2187 | 2183 |
2188 // Returns true if there is at least one debugger breakpoint | 2184 // Returns true if there is at least one debugger breakpoint |
2189 // set in this function. | 2185 // set in this function. |
2190 bool HasBreakpoint() const; | 2186 bool HasBreakpoint() const; |
2191 | 2187 |
2192 RawContextScope* context_scope() const; | 2188 RawContextScope* context_scope() const; |
2193 void set_context_scope(const ContextScope& value) const; | 2189 void set_context_scope(const ContextScope& value) const; |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3711 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); | 3707 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); |
3712 friend class Class; | 3708 friend class Class; |
3713 friend class Object; | 3709 friend class Object; |
3714 friend class RawObjectPool; | 3710 friend class RawObjectPool; |
3715 }; | 3711 }; |
3716 | 3712 |
3717 | 3713 |
3718 class Instructions : public Object { | 3714 class Instructions : public Object { |
3719 public: | 3715 public: |
3720 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). | 3716 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). |
| 3717 RawCode* code() const { return raw_ptr()->code_; } |
| 3718 static intptr_t code_offset() { |
| 3719 return OFFSET_OF(RawInstructions, code_); |
| 3720 } |
| 3721 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } |
| 3722 static intptr_t object_pool_offset() { |
| 3723 return OFFSET_OF(RawInstructions, object_pool_); |
| 3724 } |
3721 | 3725 |
3722 uword EntryPoint() const { | 3726 uword EntryPoint() const { |
3723 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); | 3727 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); |
3724 } | 3728 } |
3725 | 3729 |
3726 static const intptr_t kMaxElements = (kMaxInt32 - | 3730 static const intptr_t kMaxElements = (kMaxInt32 - |
3727 (sizeof(RawInstructions) + | 3731 (sizeof(RawInstructions) + |
3728 sizeof(RawObject) + | 3732 sizeof(RawObject) + |
3729 (2 * OS::kMaxPreferredCodeAlignment))); | 3733 (2 * OS::kMaxPreferredCodeAlignment))); |
3730 | 3734 |
(...skipping 18 matching lines...) Expand all Loading... |
3749 | 3753 |
3750 static RawInstructions* FromEntryPoint(uword entry_point) { | 3754 static RawInstructions* FromEntryPoint(uword entry_point) { |
3751 return reinterpret_cast<RawInstructions*>( | 3755 return reinterpret_cast<RawInstructions*>( |
3752 entry_point - HeaderSize() + kHeapObjectTag); | 3756 entry_point - HeaderSize() + kHeapObjectTag); |
3753 } | 3757 } |
3754 | 3758 |
3755 private: | 3759 private: |
3756 void set_size(intptr_t size) const { | 3760 void set_size(intptr_t size) const { |
3757 StoreNonPointer(&raw_ptr()->size_, size); | 3761 StoreNonPointer(&raw_ptr()->size_, size); |
3758 } | 3762 } |
| 3763 void set_code(RawCode* code) const { |
| 3764 StorePointer(&raw_ptr()->code_, code); |
| 3765 } |
| 3766 void set_object_pool(RawObjectPool* object_pool) const { |
| 3767 StorePointer(&raw_ptr()->object_pool_, object_pool); |
| 3768 } |
3759 | 3769 |
3760 // New is a private method as RawInstruction and RawCode objects should | 3770 // New is a private method as RawInstruction and RawCode objects should |
3761 // only be created using the Code::FinalizeCode method. This method creates | 3771 // only be created using the Code::FinalizeCode method. This method creates |
3762 // the RawInstruction and RawCode objects, sets up the pointer offsets | 3772 // the RawInstruction and RawCode objects, sets up the pointer offsets |
3763 // and links the two in a GC safe manner. | 3773 // and links the two in a GC safe manner. |
3764 static RawInstructions* New(intptr_t size); | 3774 static RawInstructions* New(intptr_t size); |
3765 | 3775 |
3766 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); | 3776 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); |
3767 friend class Class; | 3777 friend class Class; |
3768 friend class Code; | 3778 friend class Code; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4080 private: | 4090 private: |
4081 static void UnpackInto(const Array& table, | 4091 static void UnpackInto(const Array& table, |
4082 const TypedData& packed, | 4092 const TypedData& packed, |
4083 GrowableArray<DeoptInstr*>* instructions, | 4093 GrowableArray<DeoptInstr*>* instructions, |
4084 intptr_t length); | 4094 intptr_t length); |
4085 }; | 4095 }; |
4086 | 4096 |
4087 | 4097 |
4088 class Code : public Object { | 4098 class Code : public Object { |
4089 public: | 4099 public: |
4090 RawInstructions* active_instructions() const { | |
4091 return raw_ptr()->active_instructions_; | |
4092 } | |
4093 | |
4094 RawInstructions* instructions() const { return raw_ptr()->instructions_; } | 4100 RawInstructions* instructions() const { return raw_ptr()->instructions_; } |
4095 | 4101 |
4096 static intptr_t saved_instructions_offset() { | |
4097 return OFFSET_OF(RawCode, instructions_); | |
4098 } | |
4099 | |
4100 static intptr_t entry_point_offset() { | 4102 static intptr_t entry_point_offset() { |
4101 return OFFSET_OF(RawCode, entry_point_); | 4103 return OFFSET_OF(RawCode, entry_point_); |
4102 } | 4104 } |
4103 | 4105 |
4104 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } | |
4105 static intptr_t object_pool_offset() { | |
4106 return OFFSET_OF(RawCode, object_pool_); | |
4107 } | |
4108 | |
4109 intptr_t pointer_offsets_length() const { | 4106 intptr_t pointer_offsets_length() const { |
4110 return PtrOffBits::decode(raw_ptr()->state_bits_); | 4107 return PtrOffBits::decode(raw_ptr()->state_bits_); |
4111 } | 4108 } |
4112 | 4109 |
4113 bool is_optimized() const { | 4110 bool is_optimized() const { |
4114 return OptimizedBit::decode(raw_ptr()->state_bits_); | 4111 return OptimizedBit::decode(raw_ptr()->state_bits_); |
4115 } | 4112 } |
4116 void set_is_optimized(bool value) const; | 4113 void set_is_optimized(bool value) const; |
4117 bool is_alive() const { | 4114 bool is_alive() const { |
4118 return AliveBit::decode(raw_ptr()->state_bits_); | 4115 return AliveBit::decode(raw_ptr()->state_bits_); |
4119 } | 4116 } |
4120 void set_is_alive(bool value) const; | 4117 void set_is_alive(bool value) const; |
4121 | 4118 |
4122 uword EntryPoint() const { | 4119 uword EntryPoint() const { |
4123 return Instructions::Handle(instructions()).EntryPoint(); | 4120 ASSERT(raw_ptr()->entry_point_ == |
| 4121 Instructions::Handle(instructions()).EntryPoint()); |
| 4122 return raw_ptr()->entry_point_; |
4124 } | 4123 } |
4125 intptr_t Size() const { | 4124 intptr_t Size() const { |
4126 const Instructions& instr = Instructions::Handle(instructions()); | 4125 const Instructions& instr = Instructions::Handle(instructions()); |
4127 return instr.size(); | 4126 return instr.size(); |
4128 } | 4127 } |
4129 RawObjectPool* GetObjectPool() const { | 4128 RawObjectPool* GetObjectPool() const { |
4130 return object_pool(); | 4129 const Instructions& instr = Instructions::Handle(instructions()); |
| 4130 return instr.object_pool(); |
4131 } | 4131 } |
4132 bool ContainsInstructionAt(uword addr) const { | 4132 bool ContainsInstructionAt(uword addr) const { |
4133 const Instructions& instr = Instructions::Handle(instructions()); | 4133 const Instructions& instr = Instructions::Handle(instructions()); |
4134 const uword offset = addr - instr.EntryPoint(); | 4134 const uword offset = addr - instr.EntryPoint(); |
4135 return offset < static_cast<uword>(instr.size()); | 4135 return offset < static_cast<uword>(instr.size()); |
4136 } | 4136 } |
4137 | 4137 |
4138 // Returns true if there is a debugger breakpoint set in this code object. | 4138 // Returns true if there is a debugger breakpoint set in this code object. |
4139 bool HasBreakpoint() const; | 4139 bool HasBreakpoint() const; |
4140 | 4140 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4315 int32_t GetPointerOffsetAt(int index) const { | 4315 int32_t GetPointerOffsetAt(int index) const { |
4316 NoSafepointScope no_safepoint; | 4316 NoSafepointScope no_safepoint; |
4317 return *PointerOffsetAddrAt(index); | 4317 return *PointerOffsetAddrAt(index); |
4318 } | 4318 } |
4319 intptr_t GetTokenIndexOfPC(uword pc) const; | 4319 intptr_t GetTokenIndexOfPC(uword pc) const; |
4320 | 4320 |
4321 enum { | 4321 enum { |
4322 kInvalidPc = -1 | 4322 kInvalidPc = -1 |
4323 }; | 4323 }; |
4324 | 4324 |
| 4325 // Returns 0 if code is not patchable |
| 4326 uword GetEntryPatchPc() const; |
| 4327 uword GetPatchCodePc() const; |
| 4328 |
4325 uword GetLazyDeoptPc() const; | 4329 uword GetLazyDeoptPc() const; |
4326 | 4330 |
4327 // Find pc, return 0 if not found. | 4331 // Find pc, return 0 if not found. |
4328 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; | 4332 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; |
4329 intptr_t GetDeoptIdForOsr(uword pc) const; | 4333 intptr_t GetDeoptIdForOsr(uword pc) const; |
4330 | 4334 |
4331 RawString* Name() const; | 4335 RawString* Name() const; |
4332 RawString* PrettyName() const; | 4336 RawString* PrettyName() const; |
4333 | 4337 |
4334 int64_t compile_timestamp() const { | 4338 int64_t compile_timestamp() const { |
4335 return raw_ptr()->compile_timestamp_; | 4339 return raw_ptr()->compile_timestamp_; |
4336 } | 4340 } |
4337 | 4341 |
| 4342 intptr_t entry_patch_pc_offset() const { |
| 4343 return raw_ptr()->entry_patch_pc_offset_; |
| 4344 } |
| 4345 void set_entry_patch_pc_offset(intptr_t pc) const { |
| 4346 StoreNonPointer(&raw_ptr()->entry_patch_pc_offset_, pc); |
| 4347 } |
| 4348 |
| 4349 |
| 4350 intptr_t patch_code_pc_offset() const { |
| 4351 return raw_ptr()->patch_code_pc_offset_; |
| 4352 } |
| 4353 void set_patch_code_pc_offset(intptr_t pc) const { |
| 4354 StoreNonPointer(&raw_ptr()->patch_code_pc_offset_, pc); |
| 4355 } |
| 4356 |
| 4357 |
4338 intptr_t lazy_deopt_pc_offset() const { | 4358 intptr_t lazy_deopt_pc_offset() const { |
4339 return raw_ptr()->lazy_deopt_pc_offset_; | 4359 return raw_ptr()->lazy_deopt_pc_offset_; |
4340 } | 4360 } |
4341 void set_lazy_deopt_pc_offset(intptr_t pc) const { | 4361 void set_lazy_deopt_pc_offset(intptr_t pc) const { |
4342 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); | 4362 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); |
4343 } | 4363 } |
4344 | 4364 |
4345 bool IsAllocationStubCode() const; | 4365 bool IsAllocationStubCode() const; |
4346 bool IsStubCode() const; | 4366 bool IsStubCode() const; |
4347 bool IsFunctionCode() const; | 4367 bool IsFunctionCode() const; |
4348 | 4368 |
4349 private: | 4369 private: |
4350 void set_state_bits(intptr_t bits) const; | 4370 void set_state_bits(intptr_t bits) const; |
4351 | 4371 |
4352 void set_object_pool(RawObjectPool* object_pool) const { | |
4353 StorePointer(&raw_ptr()->object_pool_, object_pool); | |
4354 } | |
4355 | |
4356 friend class RawObject; // For RawObject::SizeFromClass(). | 4372 friend class RawObject; // For RawObject::SizeFromClass(). |
4357 friend class RawCode; | 4373 friend class RawCode; |
4358 enum { | 4374 enum { |
4359 kOptimizedBit = 0, | 4375 kOptimizedBit = 0, |
4360 kAliveBit = 1, | 4376 kAliveBit = 1, |
4361 kPtrOffBit = 2, | 4377 kPtrOffBit = 2, |
4362 kPtrOffSize = 30, | 4378 kPtrOffSize = 30, |
4363 }; | 4379 }; |
4364 | 4380 |
4365 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; | 4381 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; |
4366 class AliveBit : public BitField<bool, kAliveBit, 1> {}; | 4382 class AliveBit : public BitField<bool, kAliveBit, 1> {}; |
4367 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; | 4383 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; |
4368 | 4384 |
4369 // An object finder visitor interface. | 4385 // An object finder visitor interface. |
4370 class FindRawCodeVisitor : public FindObjectVisitor { | 4386 class FindRawCodeVisitor : public FindObjectVisitor { |
4371 public: | 4387 public: |
4372 explicit FindRawCodeVisitor(uword pc) | 4388 explicit FindRawCodeVisitor(uword pc) |
4373 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } | 4389 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } |
4374 virtual ~FindRawCodeVisitor() { } | 4390 virtual ~FindRawCodeVisitor() { } |
4375 | 4391 |
| 4392 virtual uword filter_addr() const { return pc_; } |
| 4393 |
4376 // Check if object matches find condition. | 4394 // Check if object matches find condition. |
4377 virtual bool FindObject(RawObject* obj) const; | 4395 virtual bool FindObject(RawObject* obj) const; |
4378 | 4396 |
4379 private: | 4397 private: |
4380 const uword pc_; | 4398 const uword pc_; |
4381 | 4399 |
4382 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); | 4400 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); |
4383 }; | 4401 }; |
4384 | 4402 |
4385 static bool IsOptimized(RawCode* code) { | 4403 static bool IsOptimized(RawCode* code) { |
4386 return Code::OptimizedBit::decode(code->ptr()->state_bits_); | 4404 return Code::OptimizedBit::decode(code->ptr()->state_bits_); |
4387 } | 4405 } |
4388 | 4406 |
4389 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT | 4407 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT |
4390 | 4408 |
4391 void set_compile_timestamp(int64_t timestamp) const { | 4409 void set_compile_timestamp(int64_t timestamp) const { |
4392 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); | 4410 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); |
4393 } | 4411 } |
4394 | 4412 |
4395 void set_active_instructions(RawInstructions* instructions) const { | 4413 void set_instructions(RawInstructions* instructions) { |
4396 // RawInstructions are never allocated in New space and hence a | 4414 // RawInstructions are never allocated in New space and hence a |
4397 // store buffer update is not needed here. | 4415 // store buffer update is not needed here. |
4398 StorePointer(&raw_ptr()->active_instructions_, instructions); | |
4399 StoreNonPointer(&raw_ptr()->entry_point_, | |
4400 reinterpret_cast<uword>(instructions->ptr()) + | |
4401 Instructions::HeaderSize()); | |
4402 } | |
4403 | |
4404 void set_instructions(RawInstructions* instructions) const { | |
4405 StorePointer(&raw_ptr()->instructions_, instructions); | 4416 StorePointer(&raw_ptr()->instructions_, instructions); |
| 4417 uword entry_point = reinterpret_cast<uword>(instructions->ptr()) + |
| 4418 Instructions::HeaderSize(); |
| 4419 StoreNonPointer(&raw_ptr()->entry_point_, entry_point); |
4406 } | 4420 } |
4407 | 4421 |
4408 void set_pointer_offsets_length(intptr_t value) { | 4422 void set_pointer_offsets_length(intptr_t value) { |
4409 // The number of fixups is limited to 1-billion. | 4423 // The number of fixups is limited to 1-billion. |
4410 ASSERT(Utils::IsUint(30, value)); | 4424 ASSERT(Utils::IsUint(30, value)); |
4411 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4425 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
4412 } | 4426 } |
4413 int32_t* PointerOffsetAddrAt(int index) const { | 4427 int32_t* PointerOffsetAddrAt(int index) const { |
4414 ASSERT(index >= 0); | 4428 ASSERT(index >= 0); |
4415 ASSERT(index < pointer_offsets_length()); | 4429 ASSERT(index < pointer_offsets_length()); |
(...skipping 13 matching lines...) Expand all Loading... |
4429 | 4443 |
4430 // New is a private method as RawInstruction and RawCode objects should | 4444 // New is a private method as RawInstruction and RawCode objects should |
4431 // only be created using the Code::FinalizeCode method. This method creates | 4445 // only be created using the Code::FinalizeCode method. This method creates |
4432 // the RawInstruction and RawCode objects, sets up the pointer offsets | 4446 // the RawInstruction and RawCode objects, sets up the pointer offsets |
4433 // and links the two in a GC safe manner. | 4447 // and links the two in a GC safe manner. |
4434 static RawCode* New(intptr_t pointer_offsets_length); | 4448 static RawCode* New(intptr_t pointer_offsets_length); |
4435 | 4449 |
4436 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); | 4450 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); |
4437 friend class Class; | 4451 friend class Class; |
4438 friend class SnapshotWriter; | 4452 friend class SnapshotWriter; |
4439 friend class CodePatcher; // for set_instructions | 4453 |
4440 // So that the RawFunction pointer visitor can determine whether code the | 4454 // So that the RawFunction pointer visitor can determine whether code the |
4441 // function points to is optimized. | 4455 // function points to is optimized. |
4442 friend class RawFunction; | 4456 friend class RawFunction; |
4443 }; | 4457 }; |
4444 | 4458 |
4445 | 4459 |
4446 class Context : public Object { | 4460 class Context : public Object { |
4447 public: | 4461 public: |
4448 RawContext* parent() const { return raw_ptr()->parent_; } | 4462 RawContext* parent() const { return raw_ptr()->parent_; } |
4449 void set_parent(const Context& parent) const { | 4463 void set_parent(const Context& parent) const { |
(...skipping 3670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8120 | 8134 |
8121 | 8135 |
8122 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 8136 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
8123 intptr_t index) { | 8137 intptr_t index) { |
8124 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 8138 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
8125 } | 8139 } |
8126 | 8140 |
8127 } // namespace dart | 8141 } // namespace dart |
8128 | 8142 |
8129 #endif // VM_OBJECT_H_ | 8143 #endif // VM_OBJECT_H_ |
OLD | NEW |