OLD | NEW |
1 // Copyright (c) 2012, 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 #include "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
6 | 6 |
7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
11 #include "vm/parser.h" | 11 #include "vm/parser.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 DEFINE_FLAG(bool, compress_deopt_info, true, | 15 DEFINE_FLAG(bool, compress_deopt_info, true, |
16 "Compress the size of the deoptimization info for optimized code."); | 16 "Compress the size of the deoptimization info for optimized code."); |
17 DECLARE_FLAG(bool, trace_deoptimization); | 17 DECLARE_FLAG(bool, trace_deoptimization); |
18 | 18 |
19 DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start, | 19 DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start, |
20 intptr_t to_frame_size, | 20 intptr_t to_frame_size, |
21 const Array& object_table, | 21 const Array& object_table, |
22 intptr_t num_args, | 22 intptr_t num_args, |
23 DeoptReasonId deopt_reason) | 23 DeoptReasonId deopt_reason) |
24 : object_table_(object_table), | 24 : object_table_(object_table), |
25 to_frame_(to_frame_start), | 25 to_frame_(to_frame_start), |
26 to_frame_size_(to_frame_size), | 26 to_frame_size_(to_frame_size), |
27 from_frame_(NULL), | 27 from_frame_(NULL), |
28 from_frame_size_(0), | 28 from_frame_size_(0), |
29 registers_copy_(NULL), | 29 registers_copy_(NULL), |
30 xmm_registers_copy_(NULL), | 30 fpu_registers_copy_(NULL), |
31 num_args_(num_args), | 31 num_args_(num_args), |
32 deopt_reason_(deopt_reason), | 32 deopt_reason_(deopt_reason), |
33 isolate_(Isolate::Current()) { | 33 isolate_(Isolate::Current()) { |
34 from_frame_ = isolate_->deopt_frame_copy(); | 34 from_frame_ = isolate_->deopt_frame_copy(); |
35 from_frame_size_ = isolate_->deopt_frame_copy_size(); | 35 from_frame_size_ = isolate_->deopt_frame_copy_size(); |
36 registers_copy_ = isolate_->deopt_cpu_registers_copy(); | 36 registers_copy_ = isolate_->deopt_cpu_registers_copy(); |
37 xmm_registers_copy_ = isolate_->deopt_xmm_registers_copy(); | 37 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy(); |
38 caller_fp_ = GetFromFp(); | 38 caller_fp_ = GetFromFp(); |
39 } | 39 } |
40 | 40 |
41 | 41 |
42 intptr_t DeoptimizationContext::GetFromFp() const { | 42 intptr_t DeoptimizationContext::GetFromFp() const { |
43 return from_frame_[from_frame_size_ - 1 - num_args_ - 1]; | 43 return from_frame_[from_frame_size_ - 1 - num_args_ - 1]; |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 intptr_t DeoptimizationContext::GetFromPc() const { | 47 intptr_t DeoptimizationContext::GetFromPc() const { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 } | 346 } |
347 | 347 |
348 private: | 348 private: |
349 const Register reg_; | 349 const Register reg_; |
350 | 350 |
351 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); | 351 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); |
352 }; | 352 }; |
353 | 353 |
354 | 354 |
355 // Deoptimization instruction moving an XMM register. | 355 // Deoptimization instruction moving an XMM register. |
356 class DeoptXmmRegisterInstr: public DeoptInstr { | 356 class DeoptFpuRegisterInstr: public DeoptInstr { |
357 public: | 357 public: |
358 explicit DeoptXmmRegisterInstr(intptr_t reg_as_int) | 358 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) |
359 : reg_(static_cast<XmmRegister>(reg_as_int)) {} | 359 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
360 | 360 |
361 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 361 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
362 virtual DeoptInstr::Kind kind() const { return kXmmRegister; } | 362 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } |
363 | 363 |
364 virtual const char* ToCString() const { | 364 virtual const char* ToCString() const { |
365 return Assembler::XmmRegisterName(reg_); | 365 return Assembler::FpuRegisterName(reg_); |
366 } | 366 } |
367 | 367 |
368 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 368 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
369 double value = deopt_context->XmmRegisterValue(reg_); | 369 double value = deopt_context->FpuRegisterValue(reg_); |
370 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 370 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
371 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 371 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
372 Isolate::Current()->DeferDoubleMaterialization( | 372 Isolate::Current()->DeferDoubleMaterialization( |
373 value, reinterpret_cast<RawDouble**>(to_addr)); | 373 value, reinterpret_cast<RawDouble**>(to_addr)); |
374 } | 374 } |
375 | 375 |
376 private: | 376 private: |
377 const XmmRegister reg_; | 377 const FpuRegister reg_; |
378 | 378 |
379 DISALLOW_COPY_AND_ASSIGN(DeoptXmmRegisterInstr); | 379 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); |
380 }; | 380 }; |
381 | 381 |
382 | 382 |
383 class DeoptInt64XmmRegisterInstr: public DeoptInstr { | 383 class DeoptInt64FpuRegisterInstr: public DeoptInstr { |
384 public: | 384 public: |
385 explicit DeoptInt64XmmRegisterInstr(intptr_t reg_as_int) | 385 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) |
386 : reg_(static_cast<XmmRegister>(reg_as_int)) {} | 386 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
387 | 387 |
388 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 388 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
389 virtual DeoptInstr::Kind kind() const { return kInt64XmmRegister; } | 389 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } |
390 | 390 |
391 virtual const char* ToCString() const { | 391 virtual const char* ToCString() const { |
392 const char* format = "%s(m)"; | 392 const char* format = "%s(m)"; |
393 intptr_t len = | 393 intptr_t len = |
394 OS::SNPrint(NULL, 0, format, Assembler::XmmRegisterName(reg_)); | 394 OS::SNPrint(NULL, 0, format, Assembler::FpuRegisterName(reg_)); |
395 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 395 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
396 OS::SNPrint(chars, len + 1, format, Assembler::XmmRegisterName(reg_)); | 396 OS::SNPrint(chars, len + 1, format, Assembler::FpuRegisterName(reg_)); |
397 return chars; | 397 return chars; |
398 } | 398 } |
399 | 399 |
400 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 400 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
401 int64_t value = deopt_context->XmmRegisterValueAsInt64(reg_); | 401 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); |
402 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 402 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
403 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 403 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
404 if (Smi::IsValid64(value)) { | 404 if (Smi::IsValid64(value)) { |
405 *to_addr = reinterpret_cast<intptr_t>( | 405 *to_addr = reinterpret_cast<intptr_t>( |
406 Smi::New(static_cast<intptr_t>(value))); | 406 Smi::New(static_cast<intptr_t>(value))); |
407 } else { | 407 } else { |
408 Isolate::Current()->DeferMintMaterialization( | 408 Isolate::Current()->DeferMintMaterialization( |
409 value, reinterpret_cast<RawMint**>(to_addr)); | 409 value, reinterpret_cast<RawMint**>(to_addr)); |
410 } | 410 } |
411 } | 411 } |
412 | 412 |
413 private: | 413 private: |
414 const XmmRegister reg_; | 414 const FpuRegister reg_; |
415 | 415 |
416 DISALLOW_COPY_AND_ASSIGN(DeoptInt64XmmRegisterInstr); | 416 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); |
417 }; | 417 }; |
418 | 418 |
419 | 419 |
420 // Deoptimization instruction creating a PC marker for the code of | 420 // Deoptimization instruction creating a PC marker for the code of |
421 // function at 'object_table_index'. | 421 // function at 'object_table_index'. |
422 class DeoptPcMarkerInstr : public DeoptInstr { | 422 class DeoptPcMarkerInstr : public DeoptInstr { |
423 public: | 423 public: |
424 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 424 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
425 : object_table_index_(object_table_index) { | 425 : object_table_index_(object_table_index) { |
426 ASSERT(object_table_index >= 0); | 426 ASSERT(object_table_index >= 0); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { | 594 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { |
595 Kind kind = static_cast<Kind>(kind_as_int); | 595 Kind kind = static_cast<Kind>(kind_as_int); |
596 switch (kind) { | 596 switch (kind) { |
597 case kStackSlot: return new DeoptStackSlotInstr(from_index); | 597 case kStackSlot: return new DeoptStackSlotInstr(from_index); |
598 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); | 598 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
599 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); | 599 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); |
600 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); | 600 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); |
601 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); | 601 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); |
602 case kConstant: return new DeoptConstantInstr(from_index); | 602 case kConstant: return new DeoptConstantInstr(from_index); |
603 case kRegister: return new DeoptRegisterInstr(from_index); | 603 case kRegister: return new DeoptRegisterInstr(from_index); |
604 case kXmmRegister: return new DeoptXmmRegisterInstr(from_index); | 604 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); |
605 case kInt64XmmRegister: return new DeoptInt64XmmRegisterInstr(from_index); | 605 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); |
606 case kPcMarker: return new DeoptPcMarkerInstr(from_index); | 606 case kPcMarker: return new DeoptPcMarkerInstr(from_index); |
607 case kCallerFp: return new DeoptCallerFpInstr(); | 607 case kCallerFp: return new DeoptCallerFpInstr(); |
608 case kCallerPc: return new DeoptCallerPcInstr(); | 608 case kCallerPc: return new DeoptCallerPcInstr(); |
609 case kSuffix: return new DeoptSuffixInstr(from_index); | 609 case kSuffix: return new DeoptSuffixInstr(from_index); |
610 } | 610 } |
611 UNREACHABLE(); | 611 UNREACHABLE(); |
612 return NULL; | 612 return NULL; |
613 } | 613 } |
614 | 614 |
615 | 615 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 | 698 |
699 void DeoptInfoBuilder::AddCopy(const Location& from_loc, | 699 void DeoptInfoBuilder::AddCopy(const Location& from_loc, |
700 const Value& from_value, | 700 const Value& from_value, |
701 const intptr_t to_index) { | 701 const intptr_t to_index) { |
702 DeoptInstr* deopt_instr = NULL; | 702 DeoptInstr* deopt_instr = NULL; |
703 if (from_loc.IsConstant()) { | 703 if (from_loc.IsConstant()) { |
704 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); | 704 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); |
705 deopt_instr = new DeoptConstantInstr(object_table_index); | 705 deopt_instr = new DeoptConstantInstr(object_table_index); |
706 } else if (from_loc.IsRegister()) { | 706 } else if (from_loc.IsRegister()) { |
707 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); | 707 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); |
708 } else if (from_loc.IsXmmRegister()) { | 708 } else if (from_loc.IsFpuRegister()) { |
709 if (from_loc.representation() == Location::kDouble) { | 709 if (from_loc.representation() == Location::kDouble) { |
710 deopt_instr = new DeoptXmmRegisterInstr(from_loc.xmm_reg()); | 710 deopt_instr = new DeoptFpuRegisterInstr(from_loc.fpu_reg()); |
711 } else { | 711 } else { |
712 ASSERT(from_loc.representation() == Location::kMint); | 712 ASSERT(from_loc.representation() == Location::kMint); |
713 deopt_instr = new DeoptInt64XmmRegisterInstr(from_loc.xmm_reg()); | 713 deopt_instr = new DeoptInt64FpuRegisterInstr(from_loc.fpu_reg()); |
714 } | 714 } |
715 } else if (from_loc.IsStackSlot()) { | 715 } else if (from_loc.IsStackSlot()) { |
716 intptr_t from_index = (from_loc.stack_index() < 0) ? | 716 intptr_t from_index = (from_loc.stack_index() < 0) ? |
717 from_loc.stack_index() + num_args_ : | 717 from_loc.stack_index() + num_args_ : |
718 from_loc.stack_index() + num_args_ - | 718 from_loc.stack_index() + num_args_ - |
719 ParsedFunction::kFirstLocalSlotIndex + 1; | 719 ParsedFunction::kFirstLocalSlotIndex + 1; |
720 deopt_instr = new DeoptStackSlotInstr(from_index); | 720 deopt_instr = new DeoptStackSlotInstr(from_index); |
721 } else if (from_loc.IsDoubleStackSlot()) { | 721 } else if (from_loc.IsDoubleStackSlot()) { |
722 intptr_t from_index = (from_loc.stack_index() < 0) ? | 722 intptr_t from_index = (from_loc.stack_index() < 0) ? |
723 from_loc.stack_index() + num_args_ : | 723 from_loc.stack_index() + num_args_ : |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 Smi* offset, | 822 Smi* offset, |
823 DeoptInfo* info, | 823 DeoptInfo* info, |
824 Smi* reason) { | 824 Smi* reason) { |
825 intptr_t i = index * kEntrySize; | 825 intptr_t i = index * kEntrySize; |
826 *offset ^= table.At(i); | 826 *offset ^= table.At(i); |
827 *info ^= table.At(i + 1); | 827 *info ^= table.At(i + 1); |
828 *reason ^= table.At(i + 2); | 828 *reason ^= table.At(i + 2); |
829 } | 829 } |
830 | 830 |
831 } // namespace dart | 831 } // namespace dart |
OLD | NEW |