OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 472 matching lines...) Loading... | |
484 } | 484 } |
485 #endif | 485 #endif |
486 } | 486 } |
487 | 487 |
488 | 488 |
489 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { | 489 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { |
490 deoptimizer->DoComputeOutputFrames(); | 490 deoptimizer->DoComputeOutputFrames(); |
491 } | 491 } |
492 | 492 |
493 | 493 |
494 bool Deoptimizer::TraceEnabledFor(BailoutType type) { | 494 bool Deoptimizer::TraceEnabledFor(BailoutType deopt_type, |
495 switch (type) { | 495 StackFrame::Type frame_type) { |
496 switch (deopt_type) { | |
496 case EAGER: | 497 case EAGER: |
497 case LAZY: | 498 case LAZY: |
498 case DEBUGGER: | 499 case DEBUGGER: |
499 return FLAG_trace_deopt; | 500 return (FLAG_trace_deopt && frame_type != StackFrame::STUB) || |
501 (FLAG_trace_stub_failures && frame_type == StackFrame::STUB); | |
Sven Panne
2013/02/05 13:03:11
I think a ternary is clearer here:
return (fra
| |
500 case OSR: | 502 case OSR: |
501 return FLAG_trace_osr; | 503 return FLAG_trace_osr; |
502 } | 504 } |
503 UNREACHABLE(); | 505 UNREACHABLE(); |
504 return false; | 506 return false; |
505 } | 507 } |
506 | 508 |
507 | 509 |
508 const char* Deoptimizer::MessageFor(BailoutType type) { | 510 const char* Deoptimizer::MessageFor(BailoutType type) { |
509 switch (type) { | 511 switch (type) { |
(...skipping 23 matching lines...) Loading... | |
533 bailout_type_(type), | 535 bailout_type_(type), |
534 from_(from), | 536 from_(from), |
535 fp_to_sp_delta_(fp_to_sp_delta), | 537 fp_to_sp_delta_(fp_to_sp_delta), |
536 has_alignment_padding_(0), | 538 has_alignment_padding_(0), |
537 input_(NULL), | 539 input_(NULL), |
538 output_count_(0), | 540 output_count_(0), |
539 jsframe_count_(0), | 541 jsframe_count_(0), |
540 output_(NULL), | 542 output_(NULL), |
541 deferred_arguments_objects_values_(0), | 543 deferred_arguments_objects_values_(0), |
542 deferred_arguments_objects_(0), | 544 deferred_arguments_objects_(0), |
543 deferred_heap_numbers_(0) { | 545 deferred_heap_numbers_(0), |
546 trace_(false) { | |
544 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 547 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
545 // indicating an internal frame. | 548 // indicating an internal frame. |
546 if (function->IsSmi()) { | 549 if (function->IsSmi()) { |
547 function = NULL; | 550 function = NULL; |
548 } | 551 } |
549 if (function != NULL && function->IsOptimized()) { | 552 if (function != NULL && function->IsOptimized()) { |
550 function->shared()->increment_deopt_count(); | 553 function->shared()->increment_deopt_count(); |
551 } | 554 } |
552 compiled_code_ = FindOptimizedCode(function, optimized_code); | 555 compiled_code_ = FindOptimizedCode(function, optimized_code); |
553 if (TraceEnabledFor(type)) Trace(); | 556 StackFrame::Type frame_type = function == NULL |
557 ? StackFrame::STUB | |
558 : StackFrame::JAVA_SCRIPT; | |
559 trace_ = TraceEnabledFor(type, frame_type); | |
560 if (trace_) Trace(); | |
554 ASSERT(HEAP->allow_allocation(false)); | 561 ASSERT(HEAP->allow_allocation(false)); |
555 unsigned size = ComputeInputFrameSize(); | 562 unsigned size = ComputeInputFrameSize(); |
556 input_ = new(size) FrameDescription(size, function); | 563 input_ = new(size) FrameDescription(size, function); |
557 StackFrame::Type frame_type = function == NULL | |
558 ? StackFrame::STUB | |
559 : StackFrame::JAVA_SCRIPT; | |
560 input_->SetFrameType(frame_type); | 564 input_->SetFrameType(frame_type); |
561 } | 565 } |
562 | 566 |
563 | 567 |
564 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, | 568 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, |
565 Code* optimized_code) { | 569 Code* optimized_code) { |
566 switch (bailout_type_) { | 570 switch (bailout_type_) { |
567 case Deoptimizer::EAGER: | 571 case Deoptimizer::EAGER: |
568 ASSERT(from_ == NULL); | 572 ASSERT(from_ == NULL); |
569 return function->code(); | 573 return function->code(); |
(...skipping 140 matching lines...) Loading... | |
710 // We rely on this function not causing a GC. It is called from generated code | 714 // We rely on this function not causing a GC. It is called from generated code |
711 // without having a real stack frame in place. | 715 // without having a real stack frame in place. |
712 void Deoptimizer::DoComputeOutputFrames() { | 716 void Deoptimizer::DoComputeOutputFrames() { |
713 if (bailout_type_ == OSR) { | 717 if (bailout_type_ == OSR) { |
714 DoComputeOsrOutputFrame(); | 718 DoComputeOsrOutputFrame(); |
715 return; | 719 return; |
716 } | 720 } |
717 | 721 |
718 // Print some helpful diagnostic information. | 722 // Print some helpful diagnostic information. |
719 int64_t start = OS::Ticks(); | 723 int64_t start = OS::Ticks(); |
720 if (FLAG_trace_deopt) { | 724 if (trace_) { |
721 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", | 725 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", |
722 (bailout_type_ == LAZY ? " (lazy)" : ""), | 726 (bailout_type_ == LAZY ? " (lazy)" : ""), |
723 reinterpret_cast<intptr_t>(function_)); | 727 reinterpret_cast<intptr_t>(function_)); |
724 PrintFunctionName(); | 728 PrintFunctionName(); |
725 PrintF(" @%d]\n", bailout_id_); | 729 PrintF(" @%d]\n", bailout_id_); |
726 } | 730 } |
727 | 731 |
728 // Determine basic deoptimization information. The optimized frame is | 732 // Determine basic deoptimization information. The optimized frame is |
729 // described by the input data. | 733 // described by the input data. |
730 DeoptimizationInputData* input_data = | 734 DeoptimizationInputData* input_data = |
(...skipping 57 matching lines...) Loading... | |
788 case Translation::LITERAL: | 792 case Translation::LITERAL: |
789 case Translation::ARGUMENTS_OBJECT: | 793 case Translation::ARGUMENTS_OBJECT: |
790 case Translation::DUPLICATE: | 794 case Translation::DUPLICATE: |
791 default: | 795 default: |
792 UNREACHABLE(); | 796 UNREACHABLE(); |
793 break; | 797 break; |
794 } | 798 } |
795 } | 799 } |
796 | 800 |
797 // Print some helpful diagnostic information. | 801 // Print some helpful diagnostic information. |
798 if (FLAG_trace_deopt) { | 802 if (trace_) { |
799 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 803 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
800 int index = output_count_ - 1; // Index of the topmost frame. | 804 int index = output_count_ - 1; // Index of the topmost frame. |
801 JSFunction* function = output_[index]->GetFunction(); | 805 JSFunction* function = output_[index]->GetFunction(); |
802 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", | 806 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", |
803 reinterpret_cast<intptr_t>(function)); | 807 reinterpret_cast<intptr_t>(function)); |
804 if (function != NULL) function->PrintName(); | 808 if (function != NULL) function->PrintName(); |
805 PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," | 809 PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," |
806 " took %0.3f ms]\n", | 810 " took %0.3f ms]\n", |
807 node_id.ToInt(), | 811 node_id.ToInt(), |
808 output_[index]->GetPc(), | 812 output_[index]->GetPc(), |
(...skipping 17 matching lines...) Loading... | |
826 | 830 |
827 // Play it safe and clear all unhandlified values before we continue. | 831 // Play it safe and clear all unhandlified values before we continue. |
828 deferred_arguments_objects_values_.Clear(); | 832 deferred_arguments_objects_values_.Clear(); |
829 | 833 |
830 // Materialize all heap numbers before looking at arguments because when the | 834 // Materialize all heap numbers before looking at arguments because when the |
831 // output frames are used to materialize arguments objects later on they need | 835 // output frames are used to materialize arguments objects later on they need |
832 // to already contain valid heap numbers. | 836 // to already contain valid heap numbers. |
833 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { | 837 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { |
834 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; | 838 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; |
835 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 839 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
836 if (FLAG_trace_deopt) { | 840 if (trace_) { |
837 PrintF("Materializing a new heap number %p [%e] in slot %p\n", | 841 PrintF("Materializing a new heap number %p [%e] in slot %p\n", |
838 reinterpret_cast<void*>(*num), | 842 reinterpret_cast<void*>(*num), |
839 d.value(), | 843 d.value(), |
840 d.slot_address()); | 844 d.slot_address()); |
841 } | 845 } |
842 Memory::Object_at(d.slot_address()) = *num; | 846 Memory::Object_at(d.slot_address()) = *num; |
843 } | 847 } |
844 | 848 |
845 // Materialize arguments objects one frame at a time. | 849 // Materialize arguments objects one frame at a time. |
846 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 850 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
(...skipping 24 matching lines...) Loading... | |
871 isolate_->factory()->NewFixedArray(length); | 875 isolate_->factory()->NewFixedArray(length); |
872 ASSERT(array->length() == length); | 876 ASSERT(array->length() == length); |
873 for (int i = length - 1; i >= 0 ; --i) { | 877 for (int i = length - 1; i >= 0 ; --i) { |
874 array->set(i, *values.RemoveLast()); | 878 array->set(i, *values.RemoveLast()); |
875 } | 879 } |
876 arguments->set_elements(*array); | 880 arguments->set_elements(*array); |
877 } | 881 } |
878 } | 882 } |
879 frame->SetExpression(i, *arguments); | 883 frame->SetExpression(i, *arguments); |
880 ASSERT_EQ(Memory::Object_at(descriptor.slot_address()), *arguments); | 884 ASSERT_EQ(Memory::Object_at(descriptor.slot_address()), *arguments); |
881 if (FLAG_trace_deopt) { | 885 if (trace_) { |
882 PrintF("Materializing %sarguments object for %p: ", | 886 PrintF("Materializing %sarguments object for %p: ", |
883 frame->has_adapted_arguments() ? "(adapted) " : "", | 887 frame->has_adapted_arguments() ? "(adapted) " : "", |
884 reinterpret_cast<void*>(descriptor.slot_address())); | 888 reinterpret_cast<void*>(descriptor.slot_address())); |
885 arguments->ShortPrint(); | 889 arguments->ShortPrint(); |
886 PrintF("\n"); | 890 PrintF("\n"); |
887 } | 891 } |
888 } | 892 } |
889 } | 893 } |
890 } | 894 } |
891 } | 895 } |
(...skipping 14 matching lines...) Loading... | |
906 | 910 |
907 // Check of the heap number to materialize actually belong to the frame | 911 // Check of the heap number to materialize actually belong to the frame |
908 // being extracted. | 912 // being extracted. |
909 Address slot = d.slot_address(); | 913 Address slot = d.slot_address(); |
910 if (parameters_top <= slot && slot < parameters_bottom) { | 914 if (parameters_top <= slot && slot < parameters_bottom) { |
911 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 915 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
912 | 916 |
913 int index = (info->parameters_count() - 1) - | 917 int index = (info->parameters_count() - 1) - |
914 static_cast<int>(slot - parameters_top) / kPointerSize; | 918 static_cast<int>(slot - parameters_top) / kPointerSize; |
915 | 919 |
916 if (FLAG_trace_deopt) { | 920 if (trace_) { |
917 PrintF("Materializing a new heap number %p [%e] in slot %p" | 921 PrintF("Materializing a new heap number %p [%e] in slot %p" |
918 "for parameter slot #%d\n", | 922 "for parameter slot #%d\n", |
919 reinterpret_cast<void*>(*num), | 923 reinterpret_cast<void*>(*num), |
920 d.value(), | 924 d.value(), |
921 d.slot_address(), | 925 d.slot_address(), |
922 index); | 926 index); |
923 } | 927 } |
924 | 928 |
925 info->SetParameter(index, *num); | 929 info->SetParameter(index, *num); |
926 } else if (expressions_top <= slot && slot < expressions_bottom) { | 930 } else if (expressions_top <= slot && slot < expressions_bottom) { |
927 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); | 931 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); |
928 | 932 |
929 int index = info->expression_count() - 1 - | 933 int index = info->expression_count() - 1 - |
930 static_cast<int>(slot - expressions_top) / kPointerSize; | 934 static_cast<int>(slot - expressions_top) / kPointerSize; |
931 | 935 |
932 if (FLAG_trace_deopt) { | 936 if (trace_) { |
933 PrintF("Materializing a new heap number %p [%e] in slot %p" | 937 PrintF("Materializing a new heap number %p [%e] in slot %p" |
934 "for expression slot #%d\n", | 938 "for expression slot #%d\n", |
935 reinterpret_cast<void*>(*num), | 939 reinterpret_cast<void*>(*num), |
936 d.value(), | 940 d.value(), |
937 d.slot_address(), | 941 d.slot_address(), |
938 index); | 942 index); |
939 } | 943 } |
940 | 944 |
941 info->SetExpression(index, *num); | 945 info->SetExpression(index, *num); |
942 } | 946 } |
(...skipping 26 matching lines...) Loading... | |
969 case Translation::GETTER_STUB_FRAME: | 973 case Translation::GETTER_STUB_FRAME: |
970 case Translation::SETTER_STUB_FRAME: | 974 case Translation::SETTER_STUB_FRAME: |
971 case Translation::COMPILED_STUB_FRAME: | 975 case Translation::COMPILED_STUB_FRAME: |
972 case Translation::DUPLICATE: | 976 case Translation::DUPLICATE: |
973 UNREACHABLE(); | 977 UNREACHABLE(); |
974 return; | 978 return; |
975 | 979 |
976 case Translation::REGISTER: { | 980 case Translation::REGISTER: { |
977 int input_reg = iterator->Next(); | 981 int input_reg = iterator->Next(); |
978 intptr_t input_value = input_->GetRegister(input_reg); | 982 intptr_t input_value = input_->GetRegister(input_reg); |
979 if (FLAG_trace_deopt) { | 983 if (trace_) { |
980 PrintF( | 984 PrintF( |
981 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 985 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
982 output_[frame_index]->GetTop() + output_offset, | 986 output_[frame_index]->GetTop() + output_offset, |
983 output_offset, | 987 output_offset, |
984 input_value, | 988 input_value, |
985 converter.NameOfCPURegister(input_reg)); | 989 converter.NameOfCPURegister(input_reg)); |
986 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 990 reinterpret_cast<Object*>(input_value)->ShortPrint(); |
987 PrintF("\n"); | 991 PrintF("\n"); |
988 } | 992 } |
989 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 993 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
990 return; | 994 return; |
991 } | 995 } |
992 | 996 |
993 case Translation::INT32_REGISTER: { | 997 case Translation::INT32_REGISTER: { |
994 int input_reg = iterator->Next(); | 998 int input_reg = iterator->Next(); |
995 intptr_t value = input_->GetRegister(input_reg); | 999 intptr_t value = input_->GetRegister(input_reg); |
996 bool is_smi = Smi::IsValid(value); | 1000 bool is_smi = Smi::IsValid(value); |
997 if (FLAG_trace_deopt) { | 1001 if (trace_) { |
998 PrintF( | 1002 PrintF( |
999 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", | 1003 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", |
1000 output_[frame_index]->GetTop() + output_offset, | 1004 output_[frame_index]->GetTop() + output_offset, |
1001 output_offset, | 1005 output_offset, |
1002 value, | 1006 value, |
1003 converter.NameOfCPURegister(input_reg), | 1007 converter.NameOfCPURegister(input_reg), |
1004 is_smi ? "smi" : "heap number"); | 1008 is_smi ? "smi" : "heap number"); |
1005 } | 1009 } |
1006 if (is_smi) { | 1010 if (is_smi) { |
1007 intptr_t tagged_value = | 1011 intptr_t tagged_value = |
1008 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1012 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
1009 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 1013 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
1010 } else { | 1014 } else { |
1011 // We save the untagged value on the side and store a GC-safe | 1015 // We save the untagged value on the side and store a GC-safe |
1012 // temporary placeholder in the frame. | 1016 // temporary placeholder in the frame. |
1013 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1017 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
1014 static_cast<double>(static_cast<int32_t>(value))); | 1018 static_cast<double>(static_cast<int32_t>(value))); |
1015 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1019 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1016 } | 1020 } |
1017 return; | 1021 return; |
1018 } | 1022 } |
1019 | 1023 |
1020 case Translation::UINT32_REGISTER: { | 1024 case Translation::UINT32_REGISTER: { |
1021 int input_reg = iterator->Next(); | 1025 int input_reg = iterator->Next(); |
1022 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 1026 uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); |
1023 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 1027 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
1024 if (FLAG_trace_deopt) { | 1028 if (trace_) { |
1025 PrintF( | 1029 PrintF( |
1026 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR | 1030 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR |
1027 " ; uint %s (%s)\n", | 1031 " ; uint %s (%s)\n", |
1028 output_[frame_index]->GetTop() + output_offset, | 1032 output_[frame_index]->GetTop() + output_offset, |
1029 output_offset, | 1033 output_offset, |
1030 value, | 1034 value, |
1031 converter.NameOfCPURegister(input_reg), | 1035 converter.NameOfCPURegister(input_reg), |
1032 is_smi ? "smi" : "heap number"); | 1036 is_smi ? "smi" : "heap number"); |
1033 } | 1037 } |
1034 if (is_smi) { | 1038 if (is_smi) { |
1035 intptr_t tagged_value = | 1039 intptr_t tagged_value = |
1036 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1040 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
1037 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 1041 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
1038 } else { | 1042 } else { |
1039 // We save the untagged value on the side and store a GC-safe | 1043 // We save the untagged value on the side and store a GC-safe |
1040 // temporary placeholder in the frame. | 1044 // temporary placeholder in the frame. |
1041 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1045 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
1042 static_cast<double>(static_cast<uint32_t>(value))); | 1046 static_cast<double>(static_cast<uint32_t>(value))); |
1043 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1047 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1044 } | 1048 } |
1045 return; | 1049 return; |
1046 } | 1050 } |
1047 | 1051 |
1048 case Translation::DOUBLE_REGISTER: { | 1052 case Translation::DOUBLE_REGISTER: { |
1049 int input_reg = iterator->Next(); | 1053 int input_reg = iterator->Next(); |
1050 double value = input_->GetDoubleRegister(input_reg); | 1054 double value = input_->GetDoubleRegister(input_reg); |
1051 if (FLAG_trace_deopt) { | 1055 if (trace_) { |
1052 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", | 1056 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", |
1053 output_[frame_index]->GetTop() + output_offset, | 1057 output_[frame_index]->GetTop() + output_offset, |
1054 output_offset, | 1058 output_offset, |
1055 value, | 1059 value, |
1056 DoubleRegister::AllocationIndexToString(input_reg)); | 1060 DoubleRegister::AllocationIndexToString(input_reg)); |
1057 } | 1061 } |
1058 // We save the untagged value on the side and store a GC-safe | 1062 // We save the untagged value on the side and store a GC-safe |
1059 // temporary placeholder in the frame. | 1063 // temporary placeholder in the frame. |
1060 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 1064 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
1061 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1065 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1062 return; | 1066 return; |
1063 } | 1067 } |
1064 | 1068 |
1065 case Translation::STACK_SLOT: { | 1069 case Translation::STACK_SLOT: { |
1066 int input_slot_index = iterator->Next(); | 1070 int input_slot_index = iterator->Next(); |
1067 unsigned input_offset = | 1071 unsigned input_offset = |
1068 input_->GetOffsetFromSlotIndex(input_slot_index); | 1072 input_->GetOffsetFromSlotIndex(input_slot_index); |
1069 intptr_t input_value = input_->GetFrameSlot(input_offset); | 1073 intptr_t input_value = input_->GetFrameSlot(input_offset); |
1070 if (FLAG_trace_deopt) { | 1074 if (trace_) { |
1071 PrintF(" 0x%08" V8PRIxPTR ": ", | 1075 PrintF(" 0x%08" V8PRIxPTR ": ", |
1072 output_[frame_index]->GetTop() + output_offset); | 1076 output_[frame_index]->GetTop() + output_offset); |
1073 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", | 1077 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", |
1074 output_offset, | 1078 output_offset, |
1075 input_value, | 1079 input_value, |
1076 input_offset); | 1080 input_offset); |
1077 reinterpret_cast<Object*>(input_value)->ShortPrint(); | 1081 reinterpret_cast<Object*>(input_value)->ShortPrint(); |
1078 PrintF("\n"); | 1082 PrintF("\n"); |
1079 } | 1083 } |
1080 output_[frame_index]->SetFrameSlot(output_offset, input_value); | 1084 output_[frame_index]->SetFrameSlot(output_offset, input_value); |
1081 return; | 1085 return; |
1082 } | 1086 } |
1083 | 1087 |
1084 case Translation::INT32_STACK_SLOT: { | 1088 case Translation::INT32_STACK_SLOT: { |
1085 int input_slot_index = iterator->Next(); | 1089 int input_slot_index = iterator->Next(); |
1086 unsigned input_offset = | 1090 unsigned input_offset = |
1087 input_->GetOffsetFromSlotIndex(input_slot_index); | 1091 input_->GetOffsetFromSlotIndex(input_slot_index); |
1088 intptr_t value = input_->GetFrameSlot(input_offset); | 1092 intptr_t value = input_->GetFrameSlot(input_offset); |
1089 bool is_smi = Smi::IsValid(value); | 1093 bool is_smi = Smi::IsValid(value); |
1090 if (FLAG_trace_deopt) { | 1094 if (trace_) { |
1091 PrintF(" 0x%08" V8PRIxPTR ": ", | 1095 PrintF(" 0x%08" V8PRIxPTR ": ", |
1092 output_[frame_index]->GetTop() + output_offset); | 1096 output_[frame_index]->GetTop() + output_offset); |
1093 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", | 1097 PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n", |
1094 output_offset, | 1098 output_offset, |
1095 value, | 1099 value, |
1096 input_offset, | 1100 input_offset, |
1097 is_smi ? "smi" : "heap number"); | 1101 is_smi ? "smi" : "heap number"); |
1098 } | 1102 } |
1099 if (is_smi) { | 1103 if (is_smi) { |
1100 intptr_t tagged_value = | 1104 intptr_t tagged_value = |
1101 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1105 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
1102 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 1106 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
1103 } else { | 1107 } else { |
1104 // We save the untagged value on the side and store a GC-safe | 1108 // We save the untagged value on the side and store a GC-safe |
1105 // temporary placeholder in the frame. | 1109 // temporary placeholder in the frame. |
1106 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1110 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
1107 static_cast<double>(static_cast<int32_t>(value))); | 1111 static_cast<double>(static_cast<int32_t>(value))); |
1108 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1112 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1109 } | 1113 } |
1110 return; | 1114 return; |
1111 } | 1115 } |
1112 | 1116 |
1113 case Translation::UINT32_STACK_SLOT: { | 1117 case Translation::UINT32_STACK_SLOT: { |
1114 int input_slot_index = iterator->Next(); | 1118 int input_slot_index = iterator->Next(); |
1115 unsigned input_offset = | 1119 unsigned input_offset = |
1116 input_->GetOffsetFromSlotIndex(input_slot_index); | 1120 input_->GetOffsetFromSlotIndex(input_slot_index); |
1117 uintptr_t value = | 1121 uintptr_t value = |
1118 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 1122 static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
1119 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 1123 bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); |
1120 if (FLAG_trace_deopt) { | 1124 if (trace_) { |
1121 PrintF(" 0x%08" V8PRIxPTR ": ", | 1125 PrintF(" 0x%08" V8PRIxPTR ": ", |
1122 output_[frame_index]->GetTop() + output_offset); | 1126 output_[frame_index]->GetTop() + output_offset); |
1123 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", | 1127 PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n", |
1124 output_offset, | 1128 output_offset, |
1125 value, | 1129 value, |
1126 input_offset, | 1130 input_offset, |
1127 is_smi ? "smi" : "heap number"); | 1131 is_smi ? "smi" : "heap number"); |
1128 } | 1132 } |
1129 if (is_smi) { | 1133 if (is_smi) { |
1130 intptr_t tagged_value = | 1134 intptr_t tagged_value = |
1131 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 1135 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
1132 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 1136 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); |
1133 } else { | 1137 } else { |
1134 // We save the untagged value on the side and store a GC-safe | 1138 // We save the untagged value on the side and store a GC-safe |
1135 // temporary placeholder in the frame. | 1139 // temporary placeholder in the frame. |
1136 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, | 1140 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, |
1137 static_cast<double>(static_cast<uint32_t>(value))); | 1141 static_cast<double>(static_cast<uint32_t>(value))); |
1138 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1142 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1139 } | 1143 } |
1140 return; | 1144 return; |
1141 } | 1145 } |
1142 | 1146 |
1143 case Translation::DOUBLE_STACK_SLOT: { | 1147 case Translation::DOUBLE_STACK_SLOT: { |
1144 int input_slot_index = iterator->Next(); | 1148 int input_slot_index = iterator->Next(); |
1145 unsigned input_offset = | 1149 unsigned input_offset = |
1146 input_->GetOffsetFromSlotIndex(input_slot_index); | 1150 input_->GetOffsetFromSlotIndex(input_slot_index); |
1147 double value = input_->GetDoubleFrameSlot(input_offset); | 1151 double value = input_->GetDoubleFrameSlot(input_offset); |
1148 if (FLAG_trace_deopt) { | 1152 if (trace_) { |
1149 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", | 1153 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", |
1150 output_[frame_index]->GetTop() + output_offset, | 1154 output_[frame_index]->GetTop() + output_offset, |
1151 output_offset, | 1155 output_offset, |
1152 value, | 1156 value, |
1153 input_offset); | 1157 input_offset); |
1154 } | 1158 } |
1155 // We save the untagged value on the side and store a GC-safe | 1159 // We save the untagged value on the side and store a GC-safe |
1156 // temporary placeholder in the frame. | 1160 // temporary placeholder in the frame. |
1157 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); | 1161 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); |
1158 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); | 1162 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); |
1159 return; | 1163 return; |
1160 } | 1164 } |
1161 | 1165 |
1162 case Translation::LITERAL: { | 1166 case Translation::LITERAL: { |
1163 Object* literal = ComputeLiteral(iterator->Next()); | 1167 Object* literal = ComputeLiteral(iterator->Next()); |
1164 if (FLAG_trace_deopt) { | 1168 if (trace_) { |
1165 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 1169 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
1166 output_[frame_index]->GetTop() + output_offset, | 1170 output_[frame_index]->GetTop() + output_offset, |
1167 output_offset); | 1171 output_offset); |
1168 literal->ShortPrint(); | 1172 literal->ShortPrint(); |
1169 PrintF(" ; literal\n"); | 1173 PrintF(" ; literal\n"); |
1170 } | 1174 } |
1171 intptr_t value = reinterpret_cast<intptr_t>(literal); | 1175 intptr_t value = reinterpret_cast<intptr_t>(literal); |
1172 output_[frame_index]->SetFrameSlot(output_offset, value); | 1176 output_[frame_index]->SetFrameSlot(output_offset, value); |
1173 return; | 1177 return; |
1174 } | 1178 } |
1175 | 1179 |
1176 case Translation::ARGUMENTS_OBJECT: { | 1180 case Translation::ARGUMENTS_OBJECT: { |
1177 int args_index = iterator->Next() + 1; // Skip receiver. | 1181 int args_index = iterator->Next() + 1; // Skip receiver. |
1178 int args_length = iterator->Next() - 1; // Skip receiver. | 1182 int args_length = iterator->Next() - 1; // Skip receiver. |
1179 if (FLAG_trace_deopt) { | 1183 if (trace_) { |
1180 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", | 1184 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
1181 output_[frame_index]->GetTop() + output_offset, | 1185 output_[frame_index]->GetTop() + output_offset, |
1182 output_offset); | 1186 output_offset); |
1183 isolate_->heap()->arguments_marker()->ShortPrint(); | 1187 isolate_->heap()->arguments_marker()->ShortPrint(); |
1184 PrintF(" ; arguments object\n"); | 1188 PrintF(" ; arguments object\n"); |
1185 } | 1189 } |
1186 // Use the arguments marker value as a sentinel and fill in the arguments | 1190 // Use the arguments marker value as a sentinel and fill in the arguments |
1187 // object after the deoptimized frame is built. | 1191 // object after the deoptimized frame is built. |
1188 intptr_t value = reinterpret_cast<intptr_t>( | 1192 intptr_t value = reinterpret_cast<intptr_t>( |
1189 isolate_->heap()->arguments_marker()); | 1193 isolate_->heap()->arguments_marker()); |
(...skipping 939 matching lines...) Loading... | |
2129 | 2133 |
2130 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2134 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
2131 v->VisitPointer(BitCast<Object**>(&function_)); | 2135 v->VisitPointer(BitCast<Object**>(&function_)); |
2132 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2136 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
2133 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2137 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
2134 } | 2138 } |
2135 | 2139 |
2136 #endif // ENABLE_DEBUGGER_SUPPORT | 2140 #endif // ENABLE_DEBUGGER_SUPPORT |
2137 | 2141 |
2138 } } // namespace v8::internal | 2142 } } // namespace v8::internal |
OLD | NEW |