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