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