| 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 RUNTIME_VM_DEOPT_INSTRUCTIONS_H_ | 5 #ifndef RUNTIME_VM_DEOPT_INSTRUCTIONS_H_ |
| 6 #define RUNTIME_VM_DEOPT_INSTRUCTIONS_H_ | 6 #define RUNTIME_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 11 matching lines...) Expand all Loading... |
| 22 class Value; | 22 class Value; |
| 23 class MaterializeObjectInstr; | 23 class MaterializeObjectInstr; |
| 24 class StackFrame; | 24 class StackFrame; |
| 25 class TimelineEvent; | 25 class TimelineEvent; |
| 26 | 26 |
| 27 // Holds all data relevant for execution of deoptimization instructions. | 27 // Holds all data relevant for execution of deoptimization instructions. |
| 28 // Structure is allocated in C-heap. | 28 // Structure is allocated in C-heap. |
| 29 class DeoptContext { | 29 class DeoptContext { |
| 30 public: | 30 public: |
| 31 enum DestFrameOptions { | 31 enum DestFrameOptions { |
| 32 kDestIsOriginalFrame, // Replace the original frame with deopt frame. | 32 kDestIsOriginalFrame, // Replace the original frame with deopt frame. |
| 33 kDestIsAllocated // Write deopt frame to a buffer. | 33 kDestIsAllocated // Write deopt frame to a buffer. |
| 34 }; | 34 }; |
| 35 | 35 |
| 36 // If 'deoptimizing_code' is false, only frame is being deoptimized. | 36 // If 'deoptimizing_code' is false, only frame is being deoptimized. |
| 37 DeoptContext(const StackFrame* frame, | 37 DeoptContext(const StackFrame* frame, |
| 38 const Code& code, | 38 const Code& code, |
| 39 DestFrameOptions dest_options, | 39 DestFrameOptions dest_options, |
| 40 fpu_register_t* fpu_registers, | 40 fpu_register_t* fpu_registers, |
| 41 intptr_t* cpu_registers, | 41 intptr_t* cpu_registers, |
| 42 bool is_lazy_deopt, | 42 bool is_lazy_deopt, |
| 43 bool deoptimizing_code); | 43 bool deoptimizing_code); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 // Base pointer points to the slot with the lowest address in the frame | 109 // Base pointer points to the slot with the lowest address in the frame |
| 110 // including incoming arguments and artificial deoptimization frame | 110 // including incoming arguments and artificial deoptimization frame |
| 111 // on top of it. | 111 // on top of it. |
| 112 // Note: artificial frame created by the deoptimization stub is considered | 112 // Note: artificial frame created by the deoptimization stub is considered |
| 113 // part of the frame because it contains saved caller PC and FP that | 113 // part of the frame because it contains saved caller PC and FP that |
| 114 // deoptimization will fill in. | 114 // deoptimization will fill in. |
| 115 intptr_t* FrameBase(const StackFrame* frame) { | 115 intptr_t* FrameBase(const StackFrame* frame) { |
| 116 #if !defined(TARGET_ARCH_DBC) | 116 #if !defined(TARGET_ARCH_DBC) |
| 117 // SP of the deoptimization frame is the lowest slot because | 117 // SP of the deoptimization frame is the lowest slot because |
| 118 // stack is growing downwards. | 118 // stack is growing downwards. |
| 119 return reinterpret_cast<intptr_t*>( | 119 return reinterpret_cast<intptr_t*>(frame->sp() - |
| 120 frame->sp() - (kDartFrameFixedSize * kWordSize)); | 120 (kDartFrameFixedSize * kWordSize)); |
| 121 #else | 121 #else |
| 122 // First argument is the lowest slot because stack is growing upwards. | 122 // First argument is the lowest slot because stack is growing upwards. |
| 123 return reinterpret_cast<intptr_t*>( | 123 return reinterpret_cast<intptr_t*>( |
| 124 frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize); | 124 frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize); |
| 125 #endif // !defined(TARGET_ARCH_DBC) | 125 #endif // !defined(TARGET_ARCH_DBC) |
| 126 } | 126 } |
| 127 | 127 |
| 128 void set_dest_frame(const StackFrame* frame) { | 128 void set_dest_frame(const StackFrame* frame) { |
| 129 ASSERT(frame != NULL && dest_frame_ == NULL); | 129 ASSERT(frame != NULL && dest_frame_ == NULL); |
| 130 dest_frame_ = FrameBase(frame); | 130 dest_frame_ = FrameBase(frame); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 156 // Materializes all deferred objects. Returns the total number of | 156 // Materializes all deferred objects. Returns the total number of |
| 157 // artificial arguments used during deoptimization. | 157 // artificial arguments used during deoptimization. |
| 158 intptr_t MaterializeDeferredObjects(); | 158 intptr_t MaterializeDeferredObjects(); |
| 159 | 159 |
| 160 RawArray* DestFrameAsArray(); | 160 RawArray* DestFrameAsArray(); |
| 161 | 161 |
| 162 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 162 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 163 | 163 |
| 164 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { | 164 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { |
| 165 deferred_slots_ = new DeferredObjectRef( | 165 deferred_slots_ = new DeferredObjectRef( |
| 166 idx, | 166 idx, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 167 reinterpret_cast<RawObject**>(slot), | |
| 168 deferred_slots_); | |
| 169 } | 167 } |
| 170 | 168 |
| 171 void DeferMaterialization(double value, RawDouble** slot) { | 169 void DeferMaterialization(double value, RawDouble** slot) { |
| 172 deferred_slots_ = new DeferredDouble( | 170 deferred_slots_ = new DeferredDouble( |
| 173 value, | 171 value, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 174 reinterpret_cast<RawObject**>(slot), | |
| 175 deferred_slots_); | |
| 176 } | 172 } |
| 177 | 173 |
| 178 void DeferMintMaterialization(int64_t value, RawMint** slot) { | 174 void DeferMintMaterialization(int64_t value, RawMint** slot) { |
| 179 deferred_slots_ = new DeferredMint( | 175 deferred_slots_ = new DeferredMint( |
| 180 value, | 176 value, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 181 reinterpret_cast<RawObject**>(slot), | |
| 182 deferred_slots_); | |
| 183 } | 177 } |
| 184 | 178 |
| 185 void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) { | 179 void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) { |
| 186 deferred_slots_ = new DeferredFloat32x4( | 180 deferred_slots_ = new DeferredFloat32x4( |
| 187 value, | 181 value, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 188 reinterpret_cast<RawObject**>(slot), | |
| 189 deferred_slots_); | |
| 190 } | 182 } |
| 191 | 183 |
| 192 void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) { | 184 void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) { |
| 193 deferred_slots_ = new DeferredFloat64x2( | 185 deferred_slots_ = new DeferredFloat64x2( |
| 194 value, | 186 value, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 195 reinterpret_cast<RawObject**>(slot), | |
| 196 deferred_slots_); | |
| 197 } | 187 } |
| 198 | 188 |
| 199 void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) { | 189 void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) { |
| 200 deferred_slots_ = new DeferredInt32x4( | 190 deferred_slots_ = new DeferredInt32x4( |
| 201 value, | 191 value, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 202 reinterpret_cast<RawObject**>(slot), | |
| 203 deferred_slots_); | |
| 204 } | 192 } |
| 205 | 193 |
| 206 void DeferRetAddrMaterialization(intptr_t index, | 194 void DeferRetAddrMaterialization(intptr_t index, |
| 207 intptr_t deopt_id, | 195 intptr_t deopt_id, |
| 208 intptr_t* slot) { | 196 intptr_t* slot) { |
| 209 deferred_slots_ = new DeferredRetAddr( | 197 deferred_slots_ = new DeferredRetAddr( |
| 210 index, | 198 index, deopt_id, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 211 deopt_id, | |
| 212 reinterpret_cast<RawObject**>(slot), | |
| 213 deferred_slots_); | |
| 214 } | 199 } |
| 215 | 200 |
| 216 void DeferPcMarkerMaterialization(intptr_t index, intptr_t* slot) { | 201 void DeferPcMarkerMaterialization(intptr_t index, intptr_t* slot) { |
| 217 deferred_slots_ = new DeferredPcMarker( | 202 deferred_slots_ = new DeferredPcMarker( |
| 218 index, | 203 index, reinterpret_cast<RawObject**>(slot), deferred_slots_); |
| 219 reinterpret_cast<RawObject**>(slot), | |
| 220 deferred_slots_); | |
| 221 } | 204 } |
| 222 | 205 |
| 223 void DeferPpMaterialization(intptr_t index, RawObject** slot) { | 206 void DeferPpMaterialization(intptr_t index, RawObject** slot) { |
| 224 deferred_slots_ = new DeferredPp(index, slot, deferred_slots_); | 207 deferred_slots_ = new DeferredPp(index, slot, deferred_slots_); |
| 225 } | 208 } |
| 226 | 209 |
| 227 DeferredObject* GetDeferredObject(intptr_t idx) const { | 210 DeferredObject* GetDeferredObject(intptr_t idx) const { |
| 228 return deferred_objects_[idx]; | 211 return deferred_objects_[idx]; |
| 229 } | 212 } |
| 230 | 213 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 250 } | 233 } |
| 251 } | 234 } |
| 252 | 235 |
| 253 // Sets the materialized value for some deferred object. | 236 // Sets the materialized value for some deferred object. |
| 254 // | 237 // |
| 255 // Claims ownership of the memory for 'object'. | 238 // Claims ownership of the memory for 'object'. |
| 256 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { | 239 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { |
| 257 deferred_objects_[idx] = object; | 240 deferred_objects_[idx] = object; |
| 258 } | 241 } |
| 259 | 242 |
| 260 intptr_t DeferredObjectsCount() const { | 243 intptr_t DeferredObjectsCount() const { return deferred_objects_count_; } |
| 261 return deferred_objects_count_; | |
| 262 } | |
| 263 | 244 |
| 264 RawCode* code_; | 245 RawCode* code_; |
| 265 RawObjectPool* object_pool_; | 246 RawObjectPool* object_pool_; |
| 266 RawTypedData* deopt_info_; | 247 RawTypedData* deopt_info_; |
| 267 bool dest_frame_is_allocated_; | 248 bool dest_frame_is_allocated_; |
| 268 intptr_t* dest_frame_; | 249 intptr_t* dest_frame_; |
| 269 intptr_t dest_frame_size_; | 250 intptr_t dest_frame_size_; |
| 270 bool source_frame_is_allocated_; | 251 bool source_frame_is_allocated_; |
| 271 intptr_t* source_frame_; | 252 intptr_t* source_frame_; |
| 272 intptr_t source_frame_size_; | 253 intptr_t source_frame_size_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 284 intptr_t deferred_objects_count_; | 265 intptr_t deferred_objects_count_; |
| 285 DeferredObject** deferred_objects_; | 266 DeferredObject** deferred_objects_; |
| 286 | 267 |
| 287 const bool is_lazy_deopt_; | 268 const bool is_lazy_deopt_; |
| 288 const bool deoptimizing_code_; | 269 const bool deoptimizing_code_; |
| 289 | 270 |
| 290 DISALLOW_COPY_AND_ASSIGN(DeoptContext); | 271 DISALLOW_COPY_AND_ASSIGN(DeoptContext); |
| 291 }; | 272 }; |
| 292 | 273 |
| 293 | 274 |
| 294 | |
| 295 // Represents one deopt instruction, e.g, setup return address, store object, | 275 // Represents one deopt instruction, e.g, setup return address, store object, |
| 296 // store register, etc. The target is defined by instruction's position in | 276 // store register, etc. The target is defined by instruction's position in |
| 297 // the deopt-info array. | 277 // the deopt-info array. |
| 298 class DeoptInstr : public ZoneAllocated { | 278 class DeoptInstr : public ZoneAllocated { |
| 299 public: | 279 public: |
| 300 enum Kind { | 280 enum Kind { |
| 301 kRetAddress, | 281 kRetAddress, |
| 302 kConstant, | 282 kConstant, |
| 303 kWord, | 283 kWord, |
| 304 kDouble, | 284 kDouble, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 static intptr_t GetFieldCount(DeoptInstr* instr) { | 336 static intptr_t GetFieldCount(DeoptInstr* instr) { |
| 357 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); | 337 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); |
| 358 return instr->source_index(); | 338 return instr->source_index(); |
| 359 } | 339 } |
| 360 | 340 |
| 361 protected: | 341 protected: |
| 362 friend class DeoptInfoBuilder; | 342 friend class DeoptInfoBuilder; |
| 363 | 343 |
| 364 virtual intptr_t source_index() const = 0; | 344 virtual intptr_t source_index() const = 0; |
| 365 | 345 |
| 366 virtual const char* ArgumentsToCString() const { | 346 virtual const char* ArgumentsToCString() const { return NULL; } |
| 367 return NULL; | |
| 368 } | |
| 369 | 347 |
| 370 private: | 348 private: |
| 371 static const char* KindToCString(Kind kind); | 349 static const char* KindToCString(Kind kind); |
| 372 | 350 |
| 373 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); | 351 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); |
| 374 }; | 352 }; |
| 375 | 353 |
| 376 | 354 |
| 377 // Helper class that allows to read a value of the given register from | 355 // Helper class that allows to read a value of the given register from |
| 378 // the DeoptContext as the specified type. | 356 // the DeoptContext as the specified type. |
| 379 // It calls different method depending on which kind of register (cpu/fpu) and | 357 // It calls different method depending on which kind of register (cpu/fpu) and |
| 380 // destination types are specified. | 358 // destination types are specified. |
| 381 template<typename RegisterType, typename DestinationType> | 359 template <typename RegisterType, typename DestinationType> |
| 382 struct RegisterReader; | 360 struct RegisterReader; |
| 383 | 361 |
| 384 template<typename T> | 362 template <typename T> |
| 385 struct RegisterReader<Register, T> { | 363 struct RegisterReader<Register, T> { |
| 386 static intptr_t Read(DeoptContext* context, Register reg) { | 364 static intptr_t Read(DeoptContext* context, Register reg) { |
| 387 return context->RegisterValue(reg); | 365 return context->RegisterValue(reg); |
| 388 } | 366 } |
| 389 }; | 367 }; |
| 390 | 368 |
| 391 template<> | 369 template <> |
| 392 struct RegisterReader<FpuRegister, double> { | 370 struct RegisterReader<FpuRegister, double> { |
| 393 static double Read(DeoptContext* context, FpuRegister reg) { | 371 static double Read(DeoptContext* context, FpuRegister reg) { |
| 394 return context->FpuRegisterValue(reg); | 372 return context->FpuRegisterValue(reg); |
| 395 } | 373 } |
| 396 }; | 374 }; |
| 397 | 375 |
| 398 | 376 |
| 399 template<> | 377 template <> |
| 400 struct RegisterReader<FpuRegister, simd128_value_t> { | 378 struct RegisterReader<FpuRegister, simd128_value_t> { |
| 401 static simd128_value_t Read(DeoptContext* context, FpuRegister reg) { | 379 static simd128_value_t Read(DeoptContext* context, FpuRegister reg) { |
| 402 return context->FpuRegisterValueAsSimd128(reg); | 380 return context->FpuRegisterValueAsSimd128(reg); |
| 403 } | 381 } |
| 404 }; | 382 }; |
| 405 | 383 |
| 406 | 384 |
| 407 // Class that encapsulates reading and writing of values that were either in | 385 // Class that encapsulates reading and writing of values that were either in |
| 408 // the registers in the optimized code or were spilled from those registers | 386 // the registers in the optimized code or were spilled from those registers |
| 409 // to the stack. | 387 // to the stack. |
| 410 template<typename RegisterType> | 388 template <typename RegisterType> |
| 411 class RegisterSource { | 389 class RegisterSource { |
| 412 public: | 390 public: |
| 413 enum Kind { | 391 enum Kind { |
| 414 // Spilled register source represented as its spill slot. | 392 // Spilled register source represented as its spill slot. |
| 415 kStackSlot = 0, | 393 kStackSlot = 0, |
| 416 // Register source represented as its register index. | 394 // Register source represented as its register index. |
| 417 kRegister = 1 | 395 kRegister = 1 |
| 418 }; | 396 }; |
| 419 | 397 |
| 420 explicit RegisterSource(intptr_t source_index) | 398 explicit RegisterSource(intptr_t source_index) |
| 421 : source_index_(source_index) { } | 399 : source_index_(source_index) {} |
| 422 | 400 |
| 423 RegisterSource(Kind kind, intptr_t index) | 401 RegisterSource(Kind kind, intptr_t index) |
| 424 : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) { | 402 : source_index_(KindField::encode(kind) | RawIndexField::encode(index)) {} |
| 425 } | |
| 426 | 403 |
| 427 template<typename T> | 404 template <typename T> |
| 428 T Value(DeoptContext* context) const { | 405 T Value(DeoptContext* context) const { |
| 429 if (is_register()) { | 406 if (is_register()) { |
| 430 return static_cast<T>(RegisterReader<RegisterType, T>::Read( | 407 return static_cast<T>( |
| 431 context, reg())); | 408 RegisterReader<RegisterType, T>::Read(context, reg())); |
| 432 } else { | 409 } else { |
| 433 return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( | 410 return *reinterpret_cast<T*>( |
| 434 raw_index())); | 411 context->GetSourceFrameAddressAt(raw_index())); |
| 435 } | 412 } |
| 436 } | 413 } |
| 437 | 414 |
| 438 intptr_t source_index() const { return source_index_; } | 415 intptr_t source_index() const { return source_index_; } |
| 439 | 416 |
| 440 const char* ToCString() const { | 417 const char* ToCString() const { |
| 441 if (is_register()) { | 418 if (is_register()) { |
| 442 return Name(reg()); | 419 return Name(reg()); |
| 443 } else { | 420 } else { |
| 444 return Thread::Current()->zone()->PrintToString( | 421 return Thread::Current()->zone()->PrintToString("s%" Pd "", raw_index()); |
| 445 "s%" Pd "", raw_index()); | |
| 446 } | 422 } |
| 447 } | 423 } |
| 448 | 424 |
| 449 private: | 425 private: |
| 450 class KindField : public BitField<intptr_t, intptr_t, 0, 1> { }; | 426 class KindField : public BitField<intptr_t, intptr_t, 0, 1> {}; |
| 451 class RawIndexField : | 427 class RawIndexField |
| 452 public BitField<intptr_t, intptr_t, 1, kBitsPerWord - 1> { }; | 428 : public BitField<intptr_t, intptr_t, 1, kBitsPerWord - 1> {}; |
| 453 | 429 |
| 454 bool is_register() const { | 430 bool is_register() const { |
| 455 return KindField::decode(source_index_) == kRegister; | 431 return KindField::decode(source_index_) == kRegister; |
| 456 } | 432 } |
| 457 intptr_t raw_index() const { return RawIndexField::decode(source_index_); } | 433 intptr_t raw_index() const { return RawIndexField::decode(source_index_); } |
| 458 | 434 |
| 459 RegisterType reg() const { return static_cast<RegisterType>(raw_index()); } | 435 RegisterType reg() const { return static_cast<RegisterType>(raw_index()); } |
| 460 | 436 |
| 461 static const char* Name(Register reg) { | 437 static const char* Name(Register reg) { return Assembler::RegisterName(reg); } |
| 462 return Assembler::RegisterName(reg); | |
| 463 } | |
| 464 | 438 |
| 465 static const char* Name(FpuRegister fpu_reg) { | 439 static const char* Name(FpuRegister fpu_reg) { |
| 466 return Assembler::FpuRegisterName(fpu_reg); | 440 return Assembler::FpuRegisterName(fpu_reg); |
| 467 } | 441 } |
| 468 | 442 |
| 469 const intptr_t source_index_; | 443 const intptr_t source_index_; |
| 470 }; | 444 }; |
| 471 | 445 |
| 472 | 446 |
| 473 typedef RegisterSource<Register> CpuRegisterSource; | 447 typedef RegisterSource<Register> CpuRegisterSource; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 ASSERT(frame_start_ == -1); | 492 ASSERT(frame_start_ == -1); |
| 519 frame_start_ = instructions_.length(); | 493 frame_start_ = instructions_.length(); |
| 520 } | 494 } |
| 521 | 495 |
| 522 private: | 496 private: |
| 523 friend class CompilerDeoptInfo; // For current_info_number_. | 497 friend class CompilerDeoptInfo; // For current_info_number_. |
| 524 | 498 |
| 525 class TrieNode; | 499 class TrieNode; |
| 526 | 500 |
| 527 CpuRegisterSource ToCpuRegisterSource(const Location& loc); | 501 CpuRegisterSource ToCpuRegisterSource(const Location& loc); |
| 528 FpuRegisterSource ToFpuRegisterSource(const Location& loc, | 502 FpuRegisterSource ToFpuRegisterSource( |
| 529 Location::Kind expected_stack_slot_kind); | 503 const Location& loc, |
| 504 Location::Kind expected_stack_slot_kind); |
| 530 | 505 |
| 531 intptr_t FindOrAddObjectInTable(const Object& obj) const; | 506 intptr_t FindOrAddObjectInTable(const Object& obj) const; |
| 532 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; | 507 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; |
| 533 intptr_t CalculateStackIndex(const Location& source_loc) const; | 508 intptr_t CalculateStackIndex(const Location& source_loc) const; |
| 534 | 509 |
| 535 intptr_t FrameSize() const { | 510 intptr_t FrameSize() const { |
| 536 ASSERT(frame_start_ != -1); | 511 ASSERT(frame_start_ != -1); |
| 537 const intptr_t frame_size = instructions_.length() - frame_start_; | 512 const intptr_t frame_size = instructions_.length() - frame_start_; |
| 538 ASSERT(frame_size >= 0); | 513 ASSERT(frame_size >= 0); |
| 539 return frame_size; | 514 return frame_size; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 // Set the output parameters (offset, info, reason) to the entry values at | 559 // Set the output parameters (offset, info, reason) to the entry values at |
| 585 // the index into the table (not an array index). | 560 // the index into the table (not an array index). |
| 586 static void GetEntry(const Array& table, | 561 static void GetEntry(const Array& table, |
| 587 intptr_t index, | 562 intptr_t index, |
| 588 Smi* offset, | 563 Smi* offset, |
| 589 TypedData* info, | 564 TypedData* info, |
| 590 Smi* reason_and_flags); | 565 Smi* reason_and_flags); |
| 591 | 566 |
| 592 static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason, | 567 static RawSmi* EncodeReasonAndFlags(ICData::DeoptReasonId reason, |
| 593 uint32_t flags) { | 568 uint32_t flags) { |
| 594 return Smi::New(ReasonField::encode(reason) | | 569 return Smi::New(ReasonField::encode(reason) | FlagsField::encode(flags)); |
| 595 FlagsField::encode(flags)); | |
| 596 } | 570 } |
| 597 | 571 |
| 598 class ReasonField : | 572 class ReasonField : public BitField<intptr_t, ICData::DeoptReasonId, 0, 8> {}; |
| 599 public BitField<intptr_t, ICData::DeoptReasonId, 0, 8> { }; | 573 class FlagsField : public BitField<intptr_t, uint32_t, 8, 8> {}; |
| 600 class FlagsField : public BitField<intptr_t, uint32_t, 8, 8> { }; | |
| 601 | 574 |
| 602 private: | 575 private: |
| 603 static const intptr_t kEntrySize = 3; | 576 static const intptr_t kEntrySize = 3; |
| 604 }; | 577 }; |
| 605 | 578 |
| 606 } // namespace dart | 579 } // namespace dart |
| 607 | 580 |
| 608 #endif // RUNTIME_VM_DEOPT_INSTRUCTIONS_H_ | 581 #endif // RUNTIME_VM_DEOPT_INSTRUCTIONS_H_ |
| OLD | NEW |