 Chromium Code Reviews
 Chromium Code Reviews Issue 12490013:
  Deoptimizer support for hydrogen stubs that accept a variable number of arguments.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 12490013:
  Deoptimizer support for hydrogen stubs that accept a variable number of arguments.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| Index: src/deoptimizer.cc | 
| diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc | 
| index d077fed64a66db4e95d8512c0a81ede434b8542f..0783aba1095373bf47af67b6f30c6c052a5e6048 100644 | 
| --- a/src/deoptimizer.cc | 
| +++ b/src/deoptimizer.cc | 
| @@ -1291,29 +1291,37 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, | 
| } | 
| intptr_t caller_arg_count = 0; | 
| - if (descriptor->stack_parameter_count_ != NULL) { | 
| - caller_arg_count = | 
| - input_->GetRegister(descriptor->stack_parameter_count_->code()); | 
| - } | 
| + bool arg_count_known = descriptor->stack_parameter_count_ == NULL; | 
| // Build the Arguments object for the caller's parameters and a pointer to it. | 
| output_frame_offset -= kPointerSize; | 
| - value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 
| - (caller_arg_count - 1) * kPointerSize; | 
| - output_frame->SetFrameSlot(output_frame_offset, value); | 
| + int args_arguments_offset = output_frame_offset; | 
| + intptr_t the_hole = reinterpret_cast<intptr_t>( | 
| + isolate_->heap()->the_hole_value()); | 
| + if (arg_count_known) { | 
| + value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 
| + (caller_arg_count - 1) * kPointerSize; | 
| + } else { | 
| + value = the_hole; | 
| + } | 
| + | 
| + output_frame->SetFrameSlot(args_arguments_offset, value); | 
| if (trace_) { | 
| PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| - V8PRIxPTR " ; args.arguments\n", | 
| - top_address + output_frame_offset, output_frame_offset, value); | 
| + V8PRIxPTR " ; args.arguments %s\n", | 
| + top_address + args_arguments_offset, args_arguments_offset, value, | 
| + arg_count_known ? "" : "(the hole)"); | 
| } | 
| output_frame_offset -= kPointerSize; | 
| - value = caller_arg_count; | 
| - output_frame->SetFrameSlot(output_frame_offset, value); | 
| + int length_frame_offset = output_frame_offset; | 
| + value = arg_count_known ? caller_arg_count : the_hole; | 
| + output_frame->SetFrameSlot(length_frame_offset, value); | 
| if (trace_) { | 
| PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| - V8PRIxPTR " ; args.length\n", | 
| - top_address + output_frame_offset, output_frame_offset, value); | 
| + V8PRIxPTR " ; args.length %s\n", | 
| + top_address + length_frame_offset, length_frame_offset, value, | 
| + arg_count_known ? "" : "(the hole)"); | 
| } | 
| output_frame_offset -= kPointerSize; | 
| @@ -1332,6 +1340,19 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, | 
| DoTranslateCommand(iterator, 0, output_frame_offset); | 
| } | 
| + if (!arg_count_known) { | 
| + DoTranslateCommand(iterator, 0, length_frame_offset, true); | 
| + caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); | 
| + value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 
| + (caller_arg_count - 1) * kPointerSize; | 
| + output_frame->SetFrameSlot(args_arguments_offset, value); | 
| + if (trace_) { | 
| + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| + V8PRIxPTR " ; args.arguments\n", | 
| + top_address + args_arguments_offset, args_arguments_offset, value); | 
| + } | 
| + } | 
| + | 
| ASSERT(0 == output_frame_offset); | 
| // Copy the double registers from the input into the output frame. | 
| @@ -1342,8 +1363,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, | 
| // Compute this frame's PC, state, and continuation. | 
| Code* trampoline = NULL; | 
| - int extra = descriptor->extra_expression_stack_count_; | 
| - StubFailureTrampolineStub(extra).FindCodeInCache(&trampoline, isolate_); | 
| + bool acting_as_js_function = descriptor->acting_as_js_function_; | 
| + StubFailureTrampolineStub(acting_as_js_function).FindCodeInCache(&trampoline, | 
| + isolate_); | 
| ASSERT(trampoline != NULL); | 
| output_frame->SetPc(reinterpret_cast<intptr_t>( | 
| trampoline->instruction_start())); | 
| @@ -1487,9 +1509,21 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( | 
| #endif | 
| +static const char* TraceValueType(bool is_smi, bool is_native_value) { | 
| + if (is_native_value) { | 
| + return "native"; | 
| + } else if (is_smi) { | 
| + return "smi"; | 
| + } | 
| + | 
| + return "heap number"; | 
| +} | 
| + | 
| + | 
| void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| int frame_index, | 
| - unsigned output_offset) { | 
| + unsigned output_offset, | 
| + bool is_native_value) { | 
| 
danno
2013/03/20 21:07:33
I think an enum is better here:
enum DeoptimizerTr
 
mvstanton
2013/03/21 11:47:35
Done, though I kept a bool local is_native for the
 | 
| disasm::NameConverter converter; | 
| // A GC-safe temporary placeholder that we can put in the output frame. | 
| const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 
| @@ -1535,7 +1569,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| case Translation::INT32_REGISTER: { | 
| int input_reg = iterator->Next(); | 
| intptr_t value = input_->GetRegister(input_reg); | 
| - bool is_smi = Smi::IsValid(value); | 
| + bool is_smi = !is_native_value && Smi::IsValid(value); | 
| + | 
| if (trace_) { | 
| PrintF( | 
| " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", | 
| @@ -1543,12 +1578,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| output_offset, | 
| value, | 
| converter.NameOfCPURegister(input_reg), | 
| - is_smi ? "smi" : "heap number"); | 
| + TraceValueType(is_smi, is_native_value)); | 
| } | 
| if (is_smi) { | 
| intptr_t tagged_value = | 
| reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 
| output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 
| + } else if (is_native_value) { | 
| + output_[frame_index]->SetFrameSlot(output_offset, value); | 
| } else { | 
| // We save the untagged value on the side and store a GC-safe | 
| // temporary placeholder in the frame. | 
| @@ -1562,7 +1599,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| case Translation::UINT32_REGISTER: { | 
| int input_reg = iterator->Next(); | 
| uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg)); | 
| - bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 
| + bool is_smi = !is_native_value && | 
| + (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 
| if (trace_) { | 
| PrintF( | 
| " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR | 
| @@ -1571,12 +1609,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| output_offset, | 
| value, | 
| converter.NameOfCPURegister(input_reg), | 
| - is_smi ? "smi" : "heap number"); | 
| + TraceValueType(is_smi, is_native_value)); | 
| } | 
| if (is_smi) { | 
| intptr_t tagged_value = | 
| reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 
| output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 
| + } else if (is_native_value) { | 
| + output_[frame_index]->SetFrameSlot(output_offset, value); | 
| } else { | 
| // We save the untagged value on the side and store a GC-safe | 
| // temporary placeholder in the frame. | 
| @@ -1628,7 +1668,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| unsigned input_offset = | 
| input_->GetOffsetFromSlotIndex(input_slot_index); | 
| intptr_t value = input_->GetFrameSlot(input_offset); | 
| - bool is_smi = Smi::IsValid(value); | 
| + bool is_smi = !is_native_value && Smi::IsValid(value); | 
| if (trace_) { | 
| PrintF(" 0x%08" V8PRIxPTR ": ", | 
| output_[frame_index]->GetTop() + output_offset); | 
| @@ -1636,12 +1676,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| output_offset, | 
| value, | 
| input_offset, | 
| - is_smi ? "smi" : "heap number"); | 
| + TraceValueType(is_smi, is_native_value)); | 
| } | 
| if (is_smi) { | 
| intptr_t tagged_value = | 
| reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 
| output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 
| + } else if (is_native_value) { | 
| + output_[frame_index]->SetFrameSlot(output_offset, value); | 
| } else { | 
| // We save the untagged value on the side and store a GC-safe | 
| // temporary placeholder in the frame. | 
| @@ -1658,7 +1700,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| input_->GetOffsetFromSlotIndex(input_slot_index); | 
| uintptr_t value = | 
| static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); | 
| - bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 
| + bool is_smi = !is_native_value && | 
| + (value <= static_cast<uintptr_t>(Smi::kMaxValue)); | 
| if (trace_) { | 
| PrintF(" 0x%08" V8PRIxPTR ": ", | 
| output_[frame_index]->GetTop() + output_offset); | 
| @@ -1666,12 +1709,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 
| output_offset, | 
| value, | 
| input_offset, | 
| - is_smi ? "smi" : "heap number"); | 
| + TraceValueType(is_smi, is_native_value)); | 
| } | 
| if (is_smi) { | 
| intptr_t tagged_value = | 
| reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); | 
| output_[frame_index]->SetFrameSlot(output_offset, tagged_value); | 
| + } else if (is_native_value) { | 
| + output_[frame_index]->SetFrameSlot(output_offset, value); | 
| } else { | 
| // We save the untagged value on the side and store a GC-safe | 
| // temporary placeholder in the frame. |