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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 } | 347 } |
348 | 348 |
349 private: | 349 private: |
350 const Register reg_; | 350 const Register reg_; |
351 | 351 |
352 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); | 352 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); |
353 }; | 353 }; |
354 | 354 |
355 | 355 |
356 // Deoptimization instruction moving an XMM register. | 356 // Deoptimization instruction moving an XMM register. |
357 class DeoptXmmRegisterInstr: public DeoptInstr { | 357 class DeoptFpuRegisterInstr: public DeoptInstr { |
358 public: | 358 public: |
359 explicit DeoptXmmRegisterInstr(intptr_t reg_as_int) | 359 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) |
360 : reg_(static_cast<XmmRegister>(reg_as_int)) {} | 360 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
361 | 361 |
362 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 362 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
363 virtual DeoptInstr::Kind kind() const { return kXmmRegister; } | 363 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } |
364 | 364 |
365 virtual const char* ToCString() const { | 365 virtual const char* ToCString() const { |
366 return Assembler::XmmRegisterName(reg_); | 366 return Assembler::FpuRegisterName(reg_); |
367 } | 367 } |
368 | 368 |
369 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 369 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
370 double value = deopt_context->XmmRegisterValue(reg_); | 370 double value = deopt_context->FpuRegisterValue(reg_); |
371 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 371 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
372 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 372 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
373 Isolate::Current()->DeferDoubleMaterialization( | 373 Isolate::Current()->DeferDoubleMaterialization( |
374 value, reinterpret_cast<RawDouble**>(to_addr)); | 374 value, reinterpret_cast<RawDouble**>(to_addr)); |
375 } | 375 } |
376 | 376 |
377 private: | 377 private: |
378 const XmmRegister reg_; | 378 const FpuRegister reg_; |
379 | 379 |
380 DISALLOW_COPY_AND_ASSIGN(DeoptXmmRegisterInstr); | 380 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); |
381 }; | 381 }; |
382 | 382 |
383 | 383 |
384 class DeoptInt64XmmRegisterInstr: public DeoptInstr { | 384 class DeoptInt64FpuRegisterInstr: public DeoptInstr { |
385 public: | 385 public: |
386 explicit DeoptInt64XmmRegisterInstr(intptr_t reg_as_int) | 386 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) |
387 : reg_(static_cast<XmmRegister>(reg_as_int)) {} | 387 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
388 | 388 |
389 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 389 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
390 virtual DeoptInstr::Kind kind() const { return kInt64XmmRegister; } | 390 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } |
391 | 391 |
392 virtual const char* ToCString() const { | 392 virtual const char* ToCString() const { |
393 const char* format = "%s(m)"; | 393 const char* format = "%s(m)"; |
394 intptr_t len = | 394 intptr_t len = |
395 OS::SNPrint(NULL, 0, format, Assembler::XmmRegisterName(reg_)); | 395 OS::SNPrint(NULL, 0, format, Assembler::FpuRegisterName(reg_)); |
396 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 396 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
397 OS::SNPrint(chars, len + 1, format, Assembler::XmmRegisterName(reg_)); | 397 OS::SNPrint(chars, len + 1, format, Assembler::FpuRegisterName(reg_)); |
398 return chars; | 398 return chars; |
399 } | 399 } |
400 | 400 |
401 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 401 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
402 int64_t value = deopt_context->XmmRegisterValueAsInt64(reg_); | 402 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); |
403 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 403 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
404 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 404 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
405 if (Smi::IsValid64(value)) { | 405 if (Smi::IsValid64(value)) { |
406 *to_addr = reinterpret_cast<intptr_t>( | 406 *to_addr = reinterpret_cast<intptr_t>( |
407 Smi::New(static_cast<intptr_t>(value))); | 407 Smi::New(static_cast<intptr_t>(value))); |
408 } else { | 408 } else { |
409 Isolate::Current()->DeferMintMaterialization( | 409 Isolate::Current()->DeferMintMaterialization( |
410 value, reinterpret_cast<RawMint**>(to_addr)); | 410 value, reinterpret_cast<RawMint**>(to_addr)); |
411 } | 411 } |
412 } | 412 } |
413 | 413 |
414 private: | 414 private: |
415 const XmmRegister reg_; | 415 const FpuRegister reg_; |
416 | 416 |
417 DISALLOW_COPY_AND_ASSIGN(DeoptInt64XmmRegisterInstr); | 417 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); |
418 }; | 418 }; |
419 | 419 |
420 | 420 |
421 // Deoptimization instruction creating a PC marker for the code of | 421 // Deoptimization instruction creating a PC marker for the code of |
422 // function at 'object_table_index'. | 422 // function at 'object_table_index'. |
423 class DeoptPcMarkerInstr : public DeoptInstr { | 423 class DeoptPcMarkerInstr : public DeoptInstr { |
424 public: | 424 public: |
425 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 425 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
426 : object_table_index_(object_table_index) { | 426 : object_table_index_(object_table_index) { |
427 ASSERT(object_table_index >= 0); | 427 ASSERT(object_table_index >= 0); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { | 595 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { |
596 Kind kind = static_cast<Kind>(kind_as_int); | 596 Kind kind = static_cast<Kind>(kind_as_int); |
597 switch (kind) { | 597 switch (kind) { |
598 case kStackSlot: return new DeoptStackSlotInstr(from_index); | 598 case kStackSlot: return new DeoptStackSlotInstr(from_index); |
599 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); | 599 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
600 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); | 600 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); |
601 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); | 601 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); |
602 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); | 602 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); |
603 case kConstant: return new DeoptConstantInstr(from_index); | 603 case kConstant: return new DeoptConstantInstr(from_index); |
604 case kRegister: return new DeoptRegisterInstr(from_index); | 604 case kRegister: return new DeoptRegisterInstr(from_index); |
605 case kXmmRegister: return new DeoptXmmRegisterInstr(from_index); | 605 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); |
606 case kInt64XmmRegister: return new DeoptInt64XmmRegisterInstr(from_index); | 606 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); |
607 case kPcMarker: return new DeoptPcMarkerInstr(from_index); | 607 case kPcMarker: return new DeoptPcMarkerInstr(from_index); |
608 case kCallerFp: return new DeoptCallerFpInstr(); | 608 case kCallerFp: return new DeoptCallerFpInstr(); |
609 case kCallerPc: return new DeoptCallerPcInstr(); | 609 case kCallerPc: return new DeoptCallerPcInstr(); |
610 case kSuffix: return new DeoptSuffixInstr(from_index); | 610 case kSuffix: return new DeoptSuffixInstr(from_index); |
611 } | 611 } |
612 UNREACHABLE(); | 612 UNREACHABLE(); |
613 return NULL; | 613 return NULL; |
614 } | 614 } |
615 | 615 |
616 | 616 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 | 699 |
700 void DeoptInfoBuilder::AddCopy(const Location& from_loc, | 700 void DeoptInfoBuilder::AddCopy(const Location& from_loc, |
701 const Value& from_value, | 701 const Value& from_value, |
702 const intptr_t to_index) { | 702 const intptr_t to_index) { |
703 DeoptInstr* deopt_instr = NULL; | 703 DeoptInstr* deopt_instr = NULL; |
704 if (from_loc.IsConstant()) { | 704 if (from_loc.IsConstant()) { |
705 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); | 705 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); |
706 deopt_instr = new DeoptConstantInstr(object_table_index); | 706 deopt_instr = new DeoptConstantInstr(object_table_index); |
707 } else if (from_loc.IsRegister()) { | 707 } else if (from_loc.IsRegister()) { |
708 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); | 708 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); |
709 } else if (from_loc.IsXmmRegister()) { | 709 } else if (from_loc.IsFpuRegister()) { |
710 if (from_loc.representation() == Location::kDouble) { | 710 if (from_loc.representation() == Location::kDouble) { |
711 deopt_instr = new DeoptXmmRegisterInstr(from_loc.xmm_reg()); | 711 deopt_instr = new DeoptFpuRegisterInstr(from_loc.fpu_reg()); |
712 } else { | 712 } else { |
713 ASSERT(from_loc.representation() == Location::kMint); | 713 ASSERT(from_loc.representation() == Location::kMint); |
714 deopt_instr = new DeoptInt64XmmRegisterInstr(from_loc.xmm_reg()); | 714 deopt_instr = new DeoptInt64FpuRegisterInstr(from_loc.fpu_reg()); |
715 } | 715 } |
716 } else if (from_loc.IsStackSlot()) { | 716 } else if (from_loc.IsStackSlot()) { |
717 intptr_t from_index = (from_loc.stack_index() < 0) ? | 717 intptr_t from_index = (from_loc.stack_index() < 0) ? |
718 from_loc.stack_index() + num_args_ : | 718 from_loc.stack_index() + num_args_ : |
719 from_loc.stack_index() + num_args_ - | 719 from_loc.stack_index() + num_args_ - |
720 ParsedFunction::kFirstLocalSlotIndex + 1; | 720 ParsedFunction::kFirstLocalSlotIndex + 1; |
721 deopt_instr = new DeoptStackSlotInstr(from_index); | 721 deopt_instr = new DeoptStackSlotInstr(from_index); |
722 } else if (from_loc.IsDoubleStackSlot()) { | 722 } else if (from_loc.IsDoubleStackSlot()) { |
723 intptr_t from_index = (from_loc.stack_index() < 0) ? | 723 intptr_t from_index = (from_loc.stack_index() < 0) ? |
724 from_loc.stack_index() + num_args_ : | 724 from_loc.stack_index() + num_args_ : |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 Smi* offset, | 823 Smi* offset, |
824 DeoptInfo* info, | 824 DeoptInfo* info, |
825 Smi* reason) { | 825 Smi* reason) { |
826 intptr_t i = index * kEntrySize; | 826 intptr_t i = index * kEntrySize; |
827 *offset ^= table.At(i); | 827 *offset ^= table.At(i); |
828 *info ^= table.At(i + 1); | 828 *info ^= table.At(i + 1); |
829 *reason ^= table.At(i + 2); | 829 *reason ^= table.At(i + 2); |
830 } | 830 } |
831 | 831 |
832 } // namespace dart | 832 } // namespace dart |
OLD | NEW |