| 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 |