| Index: src/deoptimizer.cc
|
| diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
|
| index 8a07afe700878d4121a1209b5c4eaee5e008bf8d..ef0d9e58094f084bbed7a4f5cec6fc64e236a0a4 100644
|
| --- a/src/deoptimizer.cc
|
| +++ b/src/deoptimizer.cc
|
| @@ -1280,29 +1280,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;
|
| @@ -1321,6 +1329,20 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
|
| DoTranslateCommand(iterator, 0, output_frame_offset);
|
| }
|
|
|
| + if (!arg_count_known) {
|
| + DoTranslateCommand(iterator, 0, length_frame_offset,
|
| + TRANSLATED_VALUE_IS_NATIVE);
|
| + 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.
|
| @@ -1331,8 +1353,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_);
|
| + StubFunctionMode function_mode = descriptor->function_mode_;
|
| + StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
|
| + isolate_);
|
| ASSERT(trampoline != NULL);
|
| output_frame->SetPc(reinterpret_cast<intptr_t>(
|
| trampoline->instruction_start()));
|
| @@ -1476,12 +1499,25 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
|
| #endif
|
|
|
|
|
| +static const char* TraceValueType(bool is_smi, bool is_native) {
|
| + if (is_native) {
|
| + return "native";
|
| + } else if (is_smi) {
|
| + return "smi";
|
| + }
|
| +
|
| + return "heap number";
|
| +}
|
| +
|
| +
|
| void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
|
| - int frame_index,
|
| - unsigned output_offset) {
|
| + int frame_index,
|
| + unsigned output_offset,
|
| + DeoptimizerTranslatedValueType value_type) {
|
| 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));
|
| + bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE;
|
|
|
| // Ignore commands marked as duplicate and act on the first non-duplicate.
|
| Translation::Opcode opcode =
|
| @@ -1524,7 +1560,9 @@ 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 = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
|
| + Smi::IsValid(value);
|
| +
|
| if (trace_) {
|
| PrintF(
|
| " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
|
| @@ -1532,15 +1570,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
|
| output_offset,
|
| value,
|
| converter.NameOfCPURegister(input_reg),
|
| - is_smi ? "smi" : "heap number");
|
| + TraceValueType(is_smi, is_native));
|
| }
|
| 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 (value_type == TRANSLATED_VALUE_IS_NATIVE) {
|
| + 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.
|
| + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
|
| AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
|
| static_cast<double>(static_cast<int32_t>(value)));
|
| output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
|
| @@ -1551,7 +1592,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 = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
|
| + (value <= static_cast<uintptr_t>(Smi::kMaxValue));
|
| if (trace_) {
|
| PrintF(
|
| " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
|
| @@ -1560,15 +1602,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
|
| output_offset,
|
| value,
|
| converter.NameOfCPURegister(input_reg),
|
| - is_smi ? "smi" : "heap number");
|
| + TraceValueType(is_smi, is_native));
|
| }
|
| 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 (value_type == TRANSLATED_VALUE_IS_NATIVE) {
|
| + 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.
|
| + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
|
| AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
|
| static_cast<double>(static_cast<uint32_t>(value)));
|
| output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
|
| @@ -1617,7 +1662,8 @@ 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 = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
|
| + Smi::IsValid(value);
|
| if (trace_) {
|
| PrintF(" 0x%08" V8PRIxPTR ": ",
|
| output_[frame_index]->GetTop() + output_offset);
|
| @@ -1625,15 +1671,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
|
| output_offset,
|
| value,
|
| input_offset,
|
| - is_smi ? "smi" : "heap number");
|
| + TraceValueType(is_smi, is_native));
|
| }
|
| 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 (value_type == TRANSLATED_VALUE_IS_NATIVE) {
|
| + 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.
|
| + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
|
| AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
|
| static_cast<double>(static_cast<int32_t>(value)));
|
| output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
|
| @@ -1647,7 +1696,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 = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
|
| + (value <= static_cast<uintptr_t>(Smi::kMaxValue));
|
| if (trace_) {
|
| PrintF(" 0x%08" V8PRIxPTR ": ",
|
| output_[frame_index]->GetTop() + output_offset);
|
| @@ -1655,15 +1705,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
|
| output_offset,
|
| value,
|
| input_offset,
|
| - is_smi ? "smi" : "heap number");
|
| + TraceValueType(is_smi, is_native));
|
| }
|
| 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 (value_type == TRANSLATED_VALUE_IS_NATIVE) {
|
| + 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.
|
| + ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED);
|
| AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
|
| static_cast<double>(static_cast<uint32_t>(value)));
|
| output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
|
|
|