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 2138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 void AttachCode(const Code& value) const; | 2149 void AttachCode(const Code& value) const; |
2150 void SetInstructions(const Code& value) const; | 2150 void SetInstructions(const Code& value) const; |
2151 void ClearCode() const; | 2151 void ClearCode() const; |
2152 | 2152 |
2153 // Disables optimized code and switches to unoptimized code. | 2153 // Disables optimized code and switches to unoptimized code. |
2154 void SwitchToUnoptimizedCode() const; | 2154 void SwitchToUnoptimizedCode() const; |
2155 | 2155 |
2156 // Return the most recently compiled and installed code for this function. | 2156 // Return the most recently compiled and installed code for this function. |
2157 // It is not the only Code object that points to this function. | 2157 // It is not the only Code object that points to this function. |
2158 RawCode* CurrentCode() const { | 2158 RawCode* CurrentCode() const { |
2159 return raw_ptr()->instructions_->ptr()->code_; | 2159 return raw_ptr()->code_; |
2160 } | 2160 } |
2161 | 2161 |
2162 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } | 2162 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } |
2163 void set_unoptimized_code(const Code& value) const; | 2163 void set_unoptimized_code(const Code& value) const; |
2164 bool HasCode() const; | 2164 bool HasCode() const; |
2165 | 2165 |
| 2166 static intptr_t code_offset() { |
| 2167 return OFFSET_OF(RawFunction, code_); |
| 2168 } |
| 2169 |
2166 static intptr_t entry_point_offset() { | 2170 static intptr_t entry_point_offset() { |
2167 return OFFSET_OF(RawFunction, entry_point_); | 2171 return OFFSET_OF(RawFunction, entry_point_); |
2168 } | 2172 } |
2169 | 2173 |
2170 // Returns true if there is at least one debugger breakpoint | 2174 // Returns true if there is at least one debugger breakpoint |
2171 // set in this function. | 2175 // set in this function. |
2172 bool HasBreakpoint() const; | 2176 bool HasBreakpoint() const; |
2173 | 2177 |
2174 RawContextScope* context_scope() const; | 2178 RawContextScope* context_scope() const; |
2175 void set_context_scope(const ContextScope& value) const; | 2179 void set_context_scope(const ContextScope& value) const; |
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3684 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); | 3688 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); |
3685 friend class Class; | 3689 friend class Class; |
3686 friend class Object; | 3690 friend class Object; |
3687 friend class RawObjectPool; | 3691 friend class RawObjectPool; |
3688 }; | 3692 }; |
3689 | 3693 |
3690 | 3694 |
3691 class Instructions : public Object { | 3695 class Instructions : public Object { |
3692 public: | 3696 public: |
3693 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). | 3697 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). |
3694 RawCode* code() const { return raw_ptr()->code_; } | |
3695 static intptr_t code_offset() { | |
3696 return OFFSET_OF(RawInstructions, code_); | |
3697 } | |
3698 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } | |
3699 static intptr_t object_pool_offset() { | |
3700 return OFFSET_OF(RawInstructions, object_pool_); | |
3701 } | |
3702 | 3698 |
3703 uword EntryPoint() const { | 3699 uword EntryPoint() const { |
3704 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); | 3700 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); |
3705 } | 3701 } |
3706 | 3702 |
3707 static const intptr_t kMaxElements = (kMaxInt32 - | 3703 static const intptr_t kMaxElements = (kMaxInt32 - |
3708 (sizeof(RawInstructions) + | 3704 (sizeof(RawInstructions) + |
3709 sizeof(RawObject) + | 3705 sizeof(RawObject) + |
3710 (2 * OS::kMaxPreferredCodeAlignment))); | 3706 (2 * OS::kMaxPreferredCodeAlignment))); |
3711 | 3707 |
(...skipping 18 matching lines...) Expand all Loading... |
3730 | 3726 |
3731 static RawInstructions* FromEntryPoint(uword entry_point) { | 3727 static RawInstructions* FromEntryPoint(uword entry_point) { |
3732 return reinterpret_cast<RawInstructions*>( | 3728 return reinterpret_cast<RawInstructions*>( |
3733 entry_point - HeaderSize() + kHeapObjectTag); | 3729 entry_point - HeaderSize() + kHeapObjectTag); |
3734 } | 3730 } |
3735 | 3731 |
3736 private: | 3732 private: |
3737 void set_size(intptr_t size) const { | 3733 void set_size(intptr_t size) const { |
3738 StoreNonPointer(&raw_ptr()->size_, size); | 3734 StoreNonPointer(&raw_ptr()->size_, size); |
3739 } | 3735 } |
3740 void set_code(RawCode* code) const { | |
3741 StorePointer(&raw_ptr()->code_, code); | |
3742 } | |
3743 void set_object_pool(RawObjectPool* object_pool) const { | |
3744 StorePointer(&raw_ptr()->object_pool_, object_pool); | |
3745 } | |
3746 | 3736 |
3747 // New is a private method as RawInstruction and RawCode objects should | 3737 // New is a private method as RawInstruction and RawCode objects should |
3748 // only be created using the Code::FinalizeCode method. This method creates | 3738 // only be created using the Code::FinalizeCode method. This method creates |
3749 // the RawInstruction and RawCode objects, sets up the pointer offsets | 3739 // the RawInstruction and RawCode objects, sets up the pointer offsets |
3750 // and links the two in a GC safe manner. | 3740 // and links the two in a GC safe manner. |
3751 static RawInstructions* New(intptr_t size); | 3741 static RawInstructions* New(intptr_t size); |
3752 | 3742 |
3753 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); | 3743 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); |
3754 friend class Class; | 3744 friend class Class; |
3755 friend class Code; | 3745 friend class Code; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4067 private: | 4057 private: |
4068 static void UnpackInto(const Array& table, | 4058 static void UnpackInto(const Array& table, |
4069 const TypedData& packed, | 4059 const TypedData& packed, |
4070 GrowableArray<DeoptInstr*>* instructions, | 4060 GrowableArray<DeoptInstr*>* instructions, |
4071 intptr_t length); | 4061 intptr_t length); |
4072 }; | 4062 }; |
4073 | 4063 |
4074 | 4064 |
4075 class Code : public Object { | 4065 class Code : public Object { |
4076 public: | 4066 public: |
| 4067 RawInstructions* active_instructions() const { |
| 4068 return raw_ptr()->active_instructions_; |
| 4069 } |
| 4070 |
4077 RawInstructions* instructions() const { return raw_ptr()->instructions_; } | 4071 RawInstructions* instructions() const { return raw_ptr()->instructions_; } |
4078 | 4072 |
| 4073 static intptr_t instructions_offset() { |
| 4074 return OFFSET_OF(RawCode, active_instructions_); |
| 4075 } |
| 4076 |
4079 static intptr_t entry_point_offset() { | 4077 static intptr_t entry_point_offset() { |
4080 return OFFSET_OF(RawCode, entry_point_); | 4078 return OFFSET_OF(RawCode, entry_point_); |
4081 } | 4079 } |
4082 | 4080 |
| 4081 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } |
| 4082 static intptr_t object_pool_offset() { |
| 4083 return OFFSET_OF(RawCode, object_pool_); |
| 4084 } |
| 4085 |
4083 intptr_t pointer_offsets_length() const { | 4086 intptr_t pointer_offsets_length() const { |
4084 return PtrOffBits::decode(raw_ptr()->state_bits_); | 4087 return PtrOffBits::decode(raw_ptr()->state_bits_); |
4085 } | 4088 } |
4086 | 4089 |
4087 bool is_optimized() const { | 4090 bool is_optimized() const { |
4088 return OptimizedBit::decode(raw_ptr()->state_bits_); | 4091 return OptimizedBit::decode(raw_ptr()->state_bits_); |
4089 } | 4092 } |
4090 void set_is_optimized(bool value) const; | 4093 void set_is_optimized(bool value) const; |
4091 bool is_alive() const { | 4094 bool is_alive() const { |
4092 return AliveBit::decode(raw_ptr()->state_bits_); | 4095 return AliveBit::decode(raw_ptr()->state_bits_); |
4093 } | 4096 } |
4094 void set_is_alive(bool value) const; | 4097 void set_is_alive(bool value) const; |
4095 | 4098 |
4096 uword EntryPoint() const { | 4099 uword EntryPoint() const { |
4097 ASSERT(raw_ptr()->entry_point_ == | 4100 return Instructions::Handle(instructions()).EntryPoint(); |
4098 Instructions::Handle(instructions()).EntryPoint()); | |
4099 return raw_ptr()->entry_point_; | |
4100 } | 4101 } |
4101 intptr_t Size() const { | 4102 intptr_t Size() const { |
4102 const Instructions& instr = Instructions::Handle(instructions()); | 4103 const Instructions& instr = Instructions::Handle(instructions()); |
4103 return instr.size(); | 4104 return instr.size(); |
4104 } | 4105 } |
4105 RawObjectPool* GetObjectPool() const { | 4106 RawObjectPool* GetObjectPool() const { |
4106 const Instructions& instr = Instructions::Handle(instructions()); | 4107 return object_pool(); |
4107 return instr.object_pool(); | |
4108 } | 4108 } |
4109 bool ContainsInstructionAt(uword addr) const { | 4109 bool ContainsInstructionAt(uword addr) const { |
4110 const Instructions& instr = Instructions::Handle(instructions()); | 4110 const Instructions& instr = Instructions::Handle(instructions()); |
4111 const uword offset = addr - instr.EntryPoint(); | 4111 const uword offset = addr - instr.EntryPoint(); |
4112 return offset < static_cast<uword>(instr.size()); | 4112 return offset < static_cast<uword>(instr.size()); |
4113 } | 4113 } |
4114 | 4114 |
4115 // Returns true if there is a debugger breakpoint set in this code object. | 4115 // Returns true if there is a debugger breakpoint set in this code object. |
4116 bool HasBreakpoint() const; | 4116 bool HasBreakpoint() const; |
4117 | 4117 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4292 int32_t GetPointerOffsetAt(int index) const { | 4292 int32_t GetPointerOffsetAt(int index) const { |
4293 NoSafepointScope no_safepoint; | 4293 NoSafepointScope no_safepoint; |
4294 return *PointerOffsetAddrAt(index); | 4294 return *PointerOffsetAddrAt(index); |
4295 } | 4295 } |
4296 intptr_t GetTokenIndexOfPC(uword pc) const; | 4296 intptr_t GetTokenIndexOfPC(uword pc) const; |
4297 | 4297 |
4298 enum { | 4298 enum { |
4299 kInvalidPc = -1 | 4299 kInvalidPc = -1 |
4300 }; | 4300 }; |
4301 | 4301 |
4302 // Returns 0 if code is not patchable | |
4303 uword GetEntryPatchPc() const; | |
4304 uword GetPatchCodePc() const; | |
4305 | |
4306 uword GetLazyDeoptPc() const; | 4302 uword GetLazyDeoptPc() const; |
4307 | 4303 |
4308 // Find pc, return 0 if not found. | 4304 // Find pc, return 0 if not found. |
4309 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; | 4305 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; |
4310 intptr_t GetDeoptIdForOsr(uword pc) const; | 4306 intptr_t GetDeoptIdForOsr(uword pc) const; |
4311 | 4307 |
4312 RawString* Name() const; | 4308 RawString* Name() const; |
4313 RawString* PrettyName() const; | 4309 RawString* PrettyName() const; |
4314 | 4310 |
4315 int64_t compile_timestamp() const { | 4311 int64_t compile_timestamp() const { |
4316 return raw_ptr()->compile_timestamp_; | 4312 return raw_ptr()->compile_timestamp_; |
4317 } | 4313 } |
4318 | 4314 |
4319 intptr_t entry_patch_pc_offset() const { | |
4320 return raw_ptr()->entry_patch_pc_offset_; | |
4321 } | |
4322 void set_entry_patch_pc_offset(intptr_t pc) const { | |
4323 StoreNonPointer(&raw_ptr()->entry_patch_pc_offset_, pc); | |
4324 } | |
4325 | |
4326 | |
4327 intptr_t patch_code_pc_offset() const { | |
4328 return raw_ptr()->patch_code_pc_offset_; | |
4329 } | |
4330 void set_patch_code_pc_offset(intptr_t pc) const { | |
4331 StoreNonPointer(&raw_ptr()->patch_code_pc_offset_, pc); | |
4332 } | |
4333 | |
4334 | |
4335 intptr_t lazy_deopt_pc_offset() const { | 4315 intptr_t lazy_deopt_pc_offset() const { |
4336 return raw_ptr()->lazy_deopt_pc_offset_; | 4316 return raw_ptr()->lazy_deopt_pc_offset_; |
4337 } | 4317 } |
4338 void set_lazy_deopt_pc_offset(intptr_t pc) const { | 4318 void set_lazy_deopt_pc_offset(intptr_t pc) const { |
4339 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); | 4319 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); |
4340 } | 4320 } |
4341 | 4321 |
4342 bool IsAllocationStubCode() const; | 4322 bool IsAllocationStubCode() const; |
4343 bool IsStubCode() const; | 4323 bool IsStubCode() const; |
4344 bool IsFunctionCode() const; | 4324 bool IsFunctionCode() const; |
4345 | 4325 |
4346 private: | 4326 private: |
4347 void set_state_bits(intptr_t bits) const; | 4327 void set_state_bits(intptr_t bits) const; |
4348 | 4328 |
| 4329 void set_object_pool(RawObjectPool* object_pool) const { |
| 4330 StorePointer(&raw_ptr()->object_pool_, object_pool); |
| 4331 } |
| 4332 |
4349 friend class RawObject; // For RawObject::SizeFromClass(). | 4333 friend class RawObject; // For RawObject::SizeFromClass(). |
4350 friend class RawCode; | 4334 friend class RawCode; |
4351 enum { | 4335 enum { |
4352 kOptimizedBit = 0, | 4336 kOptimizedBit = 0, |
4353 kAliveBit = 1, | 4337 kAliveBit = 1, |
4354 kPtrOffBit = 2, | 4338 kPtrOffBit = 2, |
4355 kPtrOffSize = 30, | 4339 kPtrOffSize = 30, |
4356 }; | 4340 }; |
4357 | 4341 |
4358 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; | 4342 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; |
4359 class AliveBit : public BitField<bool, kAliveBit, 1> {}; | 4343 class AliveBit : public BitField<bool, kAliveBit, 1> {}; |
4360 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; | 4344 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; |
4361 | 4345 |
4362 // An object finder visitor interface. | 4346 // An object finder visitor interface. |
4363 class FindRawCodeVisitor : public FindObjectVisitor { | 4347 class FindRawCodeVisitor : public FindObjectVisitor { |
4364 public: | 4348 public: |
4365 explicit FindRawCodeVisitor(uword pc) | 4349 explicit FindRawCodeVisitor(uword pc) |
4366 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } | 4350 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } |
4367 virtual ~FindRawCodeVisitor() { } | 4351 virtual ~FindRawCodeVisitor() { } |
4368 | 4352 |
4369 virtual uword filter_addr() const { return pc_; } | |
4370 | |
4371 // Check if object matches find condition. | 4353 // Check if object matches find condition. |
4372 virtual bool FindObject(RawObject* obj) const; | 4354 virtual bool FindObject(RawObject* obj) const; |
4373 | 4355 |
4374 private: | 4356 private: |
4375 const uword pc_; | 4357 const uword pc_; |
4376 | 4358 |
4377 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); | 4359 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); |
4378 }; | 4360 }; |
4379 | 4361 |
4380 static bool IsOptimized(RawCode* code) { | 4362 static bool IsOptimized(RawCode* code) { |
4381 return Code::OptimizedBit::decode(code->ptr()->state_bits_); | 4363 return Code::OptimizedBit::decode(code->ptr()->state_bits_); |
4382 } | 4364 } |
4383 | 4365 |
4384 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT | 4366 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT |
4385 | 4367 |
4386 void set_compile_timestamp(int64_t timestamp) const { | 4368 void set_compile_timestamp(int64_t timestamp) const { |
4387 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); | 4369 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); |
4388 } | 4370 } |
4389 | 4371 |
4390 void set_instructions(RawInstructions* instructions) { | 4372 void set_active_instructions(RawInstructions* instructions) const { |
4391 // RawInstructions are never allocated in New space and hence a | 4373 // RawInstructions are never allocated in New space and hence a |
4392 // store buffer update is not needed here. | 4374 // store buffer update is not needed here. |
| 4375 StorePointer(&raw_ptr()->active_instructions_, instructions); |
| 4376 StoreNonPointer(&raw_ptr()->entry_point_, |
| 4377 reinterpret_cast<uword>(instructions->ptr()) + |
| 4378 Instructions::HeaderSize()); |
| 4379 } |
| 4380 |
| 4381 void set_instructions(RawInstructions* instructions) const { |
4393 StorePointer(&raw_ptr()->instructions_, instructions); | 4382 StorePointer(&raw_ptr()->instructions_, instructions); |
4394 uword entry_point = reinterpret_cast<uword>(instructions->ptr()) + | |
4395 Instructions::HeaderSize(); | |
4396 StoreNonPointer(&raw_ptr()->entry_point_, entry_point); | |
4397 } | 4383 } |
4398 | 4384 |
4399 void set_pointer_offsets_length(intptr_t value) { | 4385 void set_pointer_offsets_length(intptr_t value) { |
4400 // The number of fixups is limited to 1-billion. | 4386 // The number of fixups is limited to 1-billion. |
4401 ASSERT(Utils::IsUint(30, value)); | 4387 ASSERT(Utils::IsUint(30, value)); |
4402 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4388 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
4403 } | 4389 } |
4404 int32_t* PointerOffsetAddrAt(int index) const { | 4390 int32_t* PointerOffsetAddrAt(int index) const { |
4405 ASSERT(index >= 0); | 4391 ASSERT(index >= 0); |
4406 ASSERT(index < pointer_offsets_length()); | 4392 ASSERT(index < pointer_offsets_length()); |
(...skipping 13 matching lines...) Expand all Loading... |
4420 | 4406 |
4421 // New is a private method as RawInstruction and RawCode objects should | 4407 // New is a private method as RawInstruction and RawCode objects should |
4422 // only be created using the Code::FinalizeCode method. This method creates | 4408 // only be created using the Code::FinalizeCode method. This method creates |
4423 // the RawInstruction and RawCode objects, sets up the pointer offsets | 4409 // the RawInstruction and RawCode objects, sets up the pointer offsets |
4424 // and links the two in a GC safe manner. | 4410 // and links the two in a GC safe manner. |
4425 static RawCode* New(intptr_t pointer_offsets_length); | 4411 static RawCode* New(intptr_t pointer_offsets_length); |
4426 | 4412 |
4427 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); | 4413 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); |
4428 friend class Class; | 4414 friend class Class; |
4429 friend class SnapshotWriter; | 4415 friend class SnapshotWriter; |
4430 | 4416 friend class CodePatcher; // for set_instructions |
4431 // So that the RawFunction pointer visitor can determine whether code the | 4417 // So that the RawFunction pointer visitor can determine whether code the |
4432 // function points to is optimized. | 4418 // function points to is optimized. |
4433 friend class RawFunction; | 4419 friend class RawFunction; |
4434 }; | 4420 }; |
4435 | 4421 |
4436 | 4422 |
4437 class Context : public Object { | 4423 class Context : public Object { |
4438 public: | 4424 public: |
4439 RawContext* parent() const { return raw_ptr()->parent_; } | 4425 RawContext* parent() const { return raw_ptr()->parent_; } |
4440 void set_parent(const Context& parent) const { | 4426 void set_parent(const Context& parent) const { |
(...skipping 3665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8106 | 8092 |
8107 | 8093 |
8108 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 8094 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
8109 intptr_t index) { | 8095 intptr_t index) { |
8110 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 8096 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
8111 } | 8097 } |
8112 | 8098 |
8113 } // namespace dart | 8099 } // namespace dart |
8114 | 8100 |
8115 #endif // VM_OBJECT_H_ | 8101 #endif // VM_OBJECT_H_ |
OLD | NEW |