| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_DEOPT_INSTRUCTIONS_H_ | 5 #ifndef VM_DEOPT_INSTRUCTIONS_H_ |
| 6 #define VM_DEOPT_INSTRUCTIONS_H_ | 6 #define VM_DEOPT_INSTRUCTIONS_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 intptr_t source_frame_size() const { return source_frame_size_; } | 91 intptr_t source_frame_size() const { return source_frame_size_; } |
| 92 intptr_t dest_frame_size() const { return dest_frame_size_; } | 92 intptr_t dest_frame_size() const { return dest_frame_size_; } |
| 93 | 93 |
| 94 RawCode* code() const { return code_; } | 94 RawCode* code() const { return code_; } |
| 95 | 95 |
| 96 ICData::DeoptReasonId deopt_reason() const { return deopt_reason_; } | 96 ICData::DeoptReasonId deopt_reason() const { return deopt_reason_; } |
| 97 bool HasDeoptFlag(ICData::DeoptFlags flag) { | 97 bool HasDeoptFlag(ICData::DeoptFlags flag) { |
| 98 return (deopt_flags_ & flag) != 0; | 98 return (deopt_flags_ & flag) != 0; |
| 99 } | 99 } |
| 100 | 100 |
| 101 RawDeoptInfo* deopt_info() const { return deopt_info_; } | 101 RawTypedData* deopt_info() const { return deopt_info_; } |
| 102 | 102 |
| 103 // Fills the destination frame but defers materialization of | 103 // Fills the destination frame but defers materialization of |
| 104 // objects. | 104 // objects. |
| 105 void FillDestFrame(); | 105 void FillDestFrame(); |
| 106 | 106 |
| 107 // Materializes all deferred objects. Returns the total number of | 107 // Materializes all deferred objects. Returns the total number of |
| 108 // artificial arguments used during deoptimization. | 108 // artificial arguments used during deoptimization. |
| 109 intptr_t MaterializeDeferredObjects(); | 109 intptr_t MaterializeDeferredObjects(); |
| 110 | 110 |
| 111 RawArray* DestFrameAsArray(); | 111 RawArray* DestFrameAsArray(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { | 199 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { |
| 200 deferred_objects_[idx] = object; | 200 deferred_objects_[idx] = object; |
| 201 } | 201 } |
| 202 | 202 |
| 203 intptr_t DeferredObjectsCount() const { | 203 intptr_t DeferredObjectsCount() const { |
| 204 return deferred_objects_count_; | 204 return deferred_objects_count_; |
| 205 } | 205 } |
| 206 | 206 |
| 207 RawCode* code_; | 207 RawCode* code_; |
| 208 RawArray* object_table_; | 208 RawArray* object_table_; |
| 209 RawDeoptInfo* deopt_info_; | 209 RawTypedData* deopt_info_; |
| 210 bool dest_frame_is_allocated_; | 210 bool dest_frame_is_allocated_; |
| 211 intptr_t* dest_frame_; | 211 intptr_t* dest_frame_; |
| 212 intptr_t dest_frame_size_; | 212 intptr_t dest_frame_size_; |
| 213 bool source_frame_is_allocated_; | 213 bool source_frame_is_allocated_; |
| 214 intptr_t* source_frame_; | 214 intptr_t* source_frame_; |
| 215 intptr_t source_frame_size_; | 215 intptr_t source_frame_size_; |
| 216 intptr_t* cpu_registers_; | 216 intptr_t* cpu_registers_; |
| 217 fpu_register_t* fpu_registers_; | 217 fpu_register_t* fpu_registers_; |
| 218 intptr_t num_args_; | 218 intptr_t num_args_; |
| 219 ICData::DeoptReasonId deopt_reason_; | 219 ICData::DeoptReasonId deopt_reason_; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 250 kMintPair, | 250 kMintPair, |
| 251 // Mints are held in one word on 64-bit architectures. | 251 // Mints are held in one word on 64-bit architectures. |
| 252 kMint, | 252 kMint, |
| 253 kInt32, | 253 kInt32, |
| 254 kUint32, | 254 kUint32, |
| 255 kPcMarker, | 255 kPcMarker, |
| 256 kPp, | 256 kPp, |
| 257 kCallerFp, | 257 kCallerFp, |
| 258 kCallerPp, | 258 kCallerPp, |
| 259 kCallerPc, | 259 kCallerPc, |
| 260 kSuffix, | |
| 261 kMaterializedObjectRef, | 260 kMaterializedObjectRef, |
| 262 kMaterializeObject | 261 kMaterializeObject |
| 263 }; | 262 }; |
| 264 | 263 |
| 265 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index); | 264 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index); |
| 266 | 265 |
| 267 DeoptInstr() {} | 266 DeoptInstr() {} |
| 268 virtual ~DeoptInstr() {} | 267 virtual ~DeoptInstr() {} |
| 269 | 268 |
| 270 virtual const char* ToCString() const { | 269 virtual const char* ToCString() const { |
| 271 const char* args = ArgumentsToCString(); | 270 const char* args = ArgumentsToCString(); |
| 272 if (args != NULL) { | 271 if (args != NULL) { |
| 273 return Thread::Current()->zone()->PrintToString( | 272 return Thread::Current()->zone()->PrintToString( |
| 274 "%s(%s)", KindToCString(kind()), args); | 273 "%s(%s)", KindToCString(kind()), args); |
| 275 } else { | 274 } else { |
| 276 return KindToCString(kind()); | 275 return KindToCString(kind()); |
| 277 } | 276 } |
| 278 } | 277 } |
| 279 | 278 |
| 280 virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0; | 279 virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0; |
| 281 | 280 |
| 282 virtual DeoptInstr::Kind kind() const = 0; | 281 virtual DeoptInstr::Kind kind() const = 0; |
| 283 | 282 |
| 284 bool Equals(const DeoptInstr& other) const { | 283 bool Equals(const DeoptInstr& other) const { |
| 285 return (kind() == other.kind()) && (source_index() == other.source_index()); | 284 return (kind() == other.kind()) && (source_index() == other.source_index()); |
| 286 } | 285 } |
| 287 | 286 |
| 288 // Decode the payload of a suffix command. Return the suffix length and | |
| 289 // set the output parameter info_number to the index of the shared suffix. | |
| 290 static intptr_t DecodeSuffix(intptr_t source_index, intptr_t* info_number); | |
| 291 | |
| 292 // Get the code and return address which is encoded in this | 287 // Get the code and return address which is encoded in this |
| 293 // kRetAfterAddress deopt instruction. | 288 // kRetAfterAddress deopt instruction. |
| 294 static uword GetRetAddress(DeoptInstr* instr, | 289 static uword GetRetAddress(DeoptInstr* instr, |
| 295 const Array& object_table, | 290 const Array& object_table, |
| 296 Code* code); | 291 Code* code); |
| 297 | 292 |
| 298 // Return number of initialized fields in the object that will be | 293 // Return number of initialized fields in the object that will be |
| 299 // materialized by kMaterializeObject instruction. | 294 // materialized by kMaterializeObject instruction. |
| 300 static intptr_t GetFieldCount(DeoptInstr* instr) { | 295 static intptr_t GetFieldCount(DeoptInstr* instr) { |
| 301 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); | 296 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 // for materialization: class of the instance to allocate and field-value | 445 // for materialization: class of the instance to allocate and field-value |
| 451 // pairs for initialization. | 446 // pairs for initialization. |
| 452 // Emitted instructions are expected to follow fixed size section of frame | 447 // Emitted instructions are expected to follow fixed size section of frame |
| 453 // emitted first. This way they become a part of the bottom-most deoptimized | 448 // emitted first. This way they become a part of the bottom-most deoptimized |
| 454 // frame and are discoverable by GC. | 449 // frame and are discoverable by GC. |
| 455 // At deoptimization they will be removed by the stub at the very end: | 450 // At deoptimization they will be removed by the stub at the very end: |
| 456 // after they were used to materialize objects. | 451 // after they were used to materialize objects. |
| 457 // Returns the index of the next stack slot. Used for verification. | 452 // Returns the index of the next stack slot. Used for verification. |
| 458 intptr_t EmitMaterializationArguments(intptr_t dest_index); | 453 intptr_t EmitMaterializationArguments(intptr_t dest_index); |
| 459 | 454 |
| 460 RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table); | 455 RawTypedData* CreateDeoptInfo(const Array& deopt_table); |
| 461 | 456 |
| 462 // Mark the actual start of the frame description after all materialization | 457 // Mark the actual start of the frame description after all materialization |
| 463 // instructions were emitted. Used for verification purposes. | 458 // instructions were emitted. Used for verification purposes. |
| 464 void MarkFrameStart() { | 459 void MarkFrameStart() { |
| 465 ASSERT(frame_start_ == -1); | 460 ASSERT(frame_start_ == -1); |
| 466 frame_start_ = instructions_.length(); | 461 frame_start_ = instructions_.length(); |
| 467 } | 462 } |
| 468 | 463 |
| 469 private: | 464 private: |
| 470 friend class CompilerDeoptInfo; // For current_info_number_. | 465 friend class CompilerDeoptInfo; // For current_info_number_. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 501 GrowableArray<MaterializeObjectInstr*> materializations_; | 496 GrowableArray<MaterializeObjectInstr*> materializations_; |
| 502 | 497 |
| 503 DISALLOW_COPY_AND_ASSIGN(DeoptInfoBuilder); | 498 DISALLOW_COPY_AND_ASSIGN(DeoptInfoBuilder); |
| 504 }; | 499 }; |
| 505 | 500 |
| 506 | 501 |
| 507 // Utilities for managing the deopt table and its entries. The table is | 502 // Utilities for managing the deopt table and its entries. The table is |
| 508 // stored in an Array in the heap. It consists of triples of (PC offset, | 503 // stored in an Array in the heap. It consists of triples of (PC offset, |
| 509 // info, reason). Elements of each entry are stored consecutively in the | 504 // info, reason). Elements of each entry are stored consecutively in the |
| 510 // array. | 505 // array. |
| 506 // TODO(vegorov): consider compressing the whole table into a single TypedData |
| 507 // object. |
| 511 class DeoptTable : public AllStatic { | 508 class DeoptTable : public AllStatic { |
| 512 public: | 509 public: |
| 513 // Return the array size in elements for a given number of table entries. | 510 // Return the array size in elements for a given number of table entries. |
| 514 static intptr_t SizeFor(intptr_t length); | 511 static intptr_t SizeFor(intptr_t length); |
| 515 | 512 |
| 516 // Set the entry at the given index into the table (not an array index). | 513 // Set the entry at the given index into the table (not an array index). |
| 517 static void SetEntry(const Array& table, | 514 static void SetEntry(const Array& table, |
| 518 intptr_t index, | 515 intptr_t index, |
| 519 const Smi& offset, | 516 const Smi& offset, |
| 520 const DeoptInfo& info, | 517 const TypedData& info, |
| 521 const Smi& reason_and_flags); | 518 const Smi& reason_and_flags); |
| 522 | 519 |
| 523 // Return the length of the table in entries. | 520 // Return the length of the table in entries. |
| 524 static intptr_t GetLength(const Array& table); | 521 static intptr_t GetLength(const Array& table); |
| 525 | 522 |
| 526 // Set the output parameters (offset, info, reason) to the entry values at | 523 // Set the output parameters (offset, info, reason) to the entry values at |
| 527 // the index into the table (not an array index). | 524 // the index into the table (not an array index). |
| 528 static void GetEntry(const Array& table, | 525 static void GetEntry(const Array& table, |
| 529 intptr_t index, | 526 intptr_t index, |
| 530 Smi* offset, | 527 Smi* offset, |
| 531 DeoptInfo* info, | 528 TypedData* info, |
| 532 Smi* reason_and_flags); | 529 Smi* reason_and_flags); |
| 533 | 530 |
| 534 static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason, | 531 static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason, |
| 535 uint32_t flags) { | 532 uint32_t flags) { |
| 536 return Smi::New(ReasonField::encode(reason) | | 533 return Smi::New(ReasonField::encode(reason) | |
| 537 FlagsField::encode(flags)); | 534 FlagsField::encode(flags)); |
| 538 } | 535 } |
| 539 | 536 |
| 540 class ReasonField : public BitField<ICData::DeoptReasonId, 0, 8> { }; | 537 class ReasonField : public BitField<ICData::DeoptReasonId, 0, 8> { }; |
| 541 class FlagsField : public BitField<uint32_t, 8, 8> { }; | 538 class FlagsField : public BitField<uint32_t, 8, 8> { }; |
| 542 | 539 |
| 543 private: | 540 private: |
| 544 static const intptr_t kEntrySize = 3; | 541 static const intptr_t kEntrySize = 3; |
| 545 }; | 542 }; |
| 546 | 543 |
| 547 } // namespace dart | 544 } // namespace dart |
| 548 | 545 |
| 549 #endif // VM_DEOPT_INSTRUCTIONS_H_ | 546 #endif // VM_DEOPT_INSTRUCTIONS_H_ |
| OLD | NEW |