Index: src/deoptimizer.cc |
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc |
index 14c1d730d01d6f7b5f8e27b314ec463a9d210443..723d3f692e6b3e45e415534d20d21e1eb977ee03 100644 |
--- a/src/deoptimizer.cc |
+++ b/src/deoptimizer.cc |
@@ -534,9 +534,8 @@ Deoptimizer::Deoptimizer(Isolate* isolate, |
output_count_(0), |
jsframe_count_(0), |
output_(NULL), |
- deferred_objects_tagged_values_(0), |
- deferred_objects_double_values_(0), |
- deferred_objects_(0), |
+ deferred_arguments_objects_values_(0), |
+ deferred_arguments_objects_(0), |
deferred_heap_numbers_(0), |
trace_(false) { |
// For COMPILED_STUBs called from builtins, the function pointer is a SMI |
@@ -1567,14 +1566,15 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, |
void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
ASSERT_NE(DEBUGGER, bailout_type_); |
- // Handlify all tagged object values before triggering any allocation. |
- List<Handle<Object> > values(deferred_objects_tagged_values_.length()); |
- for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) { |
- values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_)); |
+ // Handlify all argument object values before triggering any allocation. |
+ List<Handle<Object> > values(deferred_arguments_objects_values_.length()); |
+ for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) { |
+ values.Add(Handle<Object>(deferred_arguments_objects_values_[i], |
+ isolate_)); |
} |
// Play it safe and clear all unhandlified values before we continue. |
- deferred_objects_tagged_values_.Clear(); |
+ deferred_arguments_objects_values_.Clear(); |
// Materialize all heap numbers before looking at arguments because when the |
// output frames are used to materialize arguments objects later on they need |
@@ -1591,18 +1591,6 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
Memory::Object_at(d.slot_address()) = *num; |
} |
- // Materialize all heap numbers required for arguments objects. |
- for (int i = 0; i < values.length(); i++) { |
- if (!values.at(i)->IsTheHole()) continue; |
- double double_value = deferred_objects_double_values_[i]; |
- Handle<Object> num = isolate_->factory()->NewNumber(double_value); |
- if (trace_) { |
- PrintF("Materializing a new heap number %p [%e] for arguments object\n", |
- reinterpret_cast<void*>(*num), double_value); |
- } |
- values.Set(i, num); |
- } |
- |
// Materialize arguments objects one frame at a time. |
for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
if (frame_index != 0) it->Advance(); |
@@ -1611,9 +1599,9 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
Handle<JSObject> arguments; |
for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { |
if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) { |
- ObjectMaterializationDescriptor descriptor = |
- deferred_objects_.RemoveLast(); |
- const int length = descriptor.object_length(); |
+ ArgumentsObjectMaterializationDescriptor descriptor = |
+ deferred_arguments_objects_.RemoveLast(); |
+ const int length = descriptor.arguments_length(); |
if (arguments.is_null()) { |
if (frame->has_adapted_arguments()) { |
// Use the arguments adapter frame we just built to materialize the |
@@ -1707,7 +1695,7 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( |
#endif |
-static const char* TraceValueType(bool is_smi, bool is_native = false) { |
+static const char* TraceValueType(bool is_smi, bool is_native) { |
if (is_native) { |
return "native"; |
} else if (is_smi) { |
@@ -1718,204 +1706,6 @@ static const char* TraceValueType(bool is_smi, bool is_native = false) { |
} |
-void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
- int object_opcode, |
- int field_index) { |
- disasm::NameConverter converter; |
- Address object_slot = deferred_objects_.last().slot_address(); |
- |
- // Ignore commands marked as duplicate and act on the first non-duplicate. |
- Translation::Opcode opcode = |
- static_cast<Translation::Opcode>(iterator->Next()); |
- while (opcode == Translation::DUPLICATE) { |
- opcode = static_cast<Translation::Opcode>(iterator->Next()); |
- iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
- opcode = static_cast<Translation::Opcode>(iterator->Next()); |
- } |
- |
- switch (opcode) { |
- case Translation::BEGIN: |
- case Translation::JS_FRAME: |
- case Translation::ARGUMENTS_ADAPTOR_FRAME: |
- case Translation::CONSTRUCT_STUB_FRAME: |
- case Translation::GETTER_STUB_FRAME: |
- case Translation::SETTER_STUB_FRAME: |
- case Translation::COMPILED_STUB_FRAME: |
- case Translation::ARGUMENTS_OBJECT: |
- case Translation::DUPLICATE: |
- UNREACHABLE(); |
- return; |
- |
- case Translation::REGISTER: { |
- int input_reg = iterator->Next(); |
- intptr_t input_value = input_->GetRegister(input_reg); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("0x%08" V8PRIxPTR " ; %s ", input_value, |
- converter.NameOfCPURegister(input_reg)); |
- reinterpret_cast<Object*>(input_value)->ShortPrint(); |
- PrintF("\n"); |
- } |
- AddObjectTaggedValue(input_value); |
- return; |
- } |
- |
- case Translation::INT32_REGISTER: { |
- int input_reg = iterator->Next(); |
- intptr_t value = input_->GetRegister(input_reg); |
- bool is_smi = Smi::IsValid(value); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%" V8PRIdPTR " ; %s (%s)\n", value, |
- converter.NameOfCPURegister(input_reg), |
- TraceValueType(is_smi)); |
- } |
- if (is_smi) { |
- intptr_t tagged_value = |
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
- AddObjectTaggedValue(tagged_value); |
- } else { |
- double double_value = static_cast<double>(static_cast<int32_t>(value)); |
- AddObjectDoubleValue(double_value); |
- } |
- return; |
- } |
- |
- 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)); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value, |
- converter.NameOfCPURegister(input_reg), |
- TraceValueType(is_smi)); |
- } |
- if (is_smi) { |
- intptr_t tagged_value = |
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
- AddObjectTaggedValue(tagged_value); |
- } else { |
- double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
- AddObjectDoubleValue(double_value); |
- } |
- return; |
- } |
- |
- case Translation::DOUBLE_REGISTER: { |
- int input_reg = iterator->Next(); |
- double value = input_->GetDoubleRegister(input_reg); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%e ; %s\n", value, |
- DoubleRegister::AllocationIndexToString(input_reg)); |
- } |
- AddObjectDoubleValue(value); |
- return; |
- } |
- |
- case Translation::STACK_SLOT: { |
- int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
- intptr_t input_value = input_->GetFrameSlot(input_offset); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset); |
- reinterpret_cast<Object*>(input_value)->ShortPrint(); |
- PrintF("\n"); |
- } |
- AddObjectTaggedValue(input_value); |
- return; |
- } |
- |
- case Translation::INT32_STACK_SLOT: { |
- int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
- intptr_t value = input_->GetFrameSlot(input_offset); |
- bool is_smi = Smi::IsValid(value); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n", |
- value, input_offset, TraceValueType(is_smi)); |
- } |
- if (is_smi) { |
- intptr_t tagged_value = |
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
- AddObjectTaggedValue(tagged_value); |
- } else { |
- double double_value = static_cast<double>(static_cast<int32_t>(value)); |
- AddObjectDoubleValue(double_value); |
- } |
- return; |
- } |
- |
- case Translation::UINT32_STACK_SLOT: { |
- int input_slot_index = iterator->Next(); |
- unsigned input_offset = 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)); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n", |
- value, input_offset, TraceValueType(is_smi)); |
- } |
- if (is_smi) { |
- intptr_t tagged_value = |
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); |
- AddObjectTaggedValue(tagged_value); |
- } else { |
- double double_value = static_cast<double>(static_cast<uint32_t>(value)); |
- AddObjectDoubleValue(double_value); |
- } |
- return; |
- } |
- |
- case Translation::DOUBLE_STACK_SLOT: { |
- int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
- double value = input_->GetDoubleFrameSlot(input_offset); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- PrintF("%e ; [sp + %d]\n", value, input_offset); |
- } |
- AddObjectDoubleValue(value); |
- return; |
- } |
- |
- case Translation::LITERAL: { |
- Object* literal = ComputeLiteral(iterator->Next()); |
- if (trace_) { |
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
- reinterpret_cast<intptr_t>(object_slot), |
- field_index); |
- literal->ShortPrint(); |
- PrintF(" ; literal\n"); |
- } |
- intptr_t value = reinterpret_cast<intptr_t>(literal); |
- AddObjectTaggedValue(value); |
- return; |
- } |
- } |
-} |
- |
- |
void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
int frame_index, |
unsigned output_offset, |
@@ -1968,6 +1758,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
intptr_t value = input_->GetRegister(input_reg); |
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
Smi::IsValid(value); |
+ |
if (trace_) { |
PrintF( |
" 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", |
@@ -2045,7 +1836,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
case Translation::STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ unsigned input_offset = |
+ input_->GetOffsetFromSlotIndex(input_slot_index); |
intptr_t input_value = input_->GetFrameSlot(input_offset); |
if (trace_) { |
PrintF(" 0x%08" V8PRIxPTR ": ", |
@@ -2063,7 +1855,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
case Translation::INT32_STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ unsigned input_offset = |
+ input_->GetOffsetFromSlotIndex(input_slot_index); |
intptr_t value = input_->GetFrameSlot(input_offset); |
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
Smi::IsValid(value); |
@@ -2095,7 +1888,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
case Translation::UINT32_STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ unsigned input_offset = |
+ input_->GetOffsetFromSlotIndex(input_slot_index); |
uintptr_t value = |
static_cast<uintptr_t>(input_->GetFrameSlot(input_offset)); |
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && |
@@ -2128,7 +1922,8 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
case Translation::DOUBLE_STACK_SLOT: { |
int input_slot_index = iterator->Next(); |
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); |
+ unsigned input_offset = |
+ input_->GetOffsetFromSlotIndex(input_slot_index); |
double value = input_->GetDoubleFrameSlot(input_offset); |
if (trace_) { |
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n", |
@@ -2159,24 +1954,31 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
} |
case Translation::ARGUMENTS_OBJECT: { |
- int length = iterator->Next(); |
+ bool args_known = iterator->Next(); |
+ int args_index = iterator->Next() + 1; // Skip receiver. |
+ int args_length = iterator->Next() - 1; // Skip receiver. |
if (trace_) { |
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", |
output_[frame_index]->GetTop() + output_offset, |
output_offset); |
isolate_->heap()->arguments_marker()->ShortPrint(); |
- PrintF(" ; arguments object (length = %d)\n", length); |
+ PrintF(" ; %sarguments object\n", args_known ? "" : "dummy "); |
} |
// Use the arguments marker value as a sentinel and fill in the arguments |
// object after the deoptimized frame is built. |
intptr_t value = reinterpret_cast<intptr_t>( |
isolate_->heap()->arguments_marker()); |
- AddObjectStart(output_[frame_index]->GetTop() + output_offset, length); |
+ AddArgumentsObject( |
+ output_[frame_index]->GetTop() + output_offset, args_length); |
output_[frame_index]->SetFrameSlot(output_offset, value); |
- // We save the argument values on the side and materialize the actual |
- // arguments object after the deoptimized frame is built. |
- for (int i = 0; i < length; i++) { |
- DoTranslateObject(iterator, Translation::ARGUMENTS_OBJECT, i); |
+ // We save the tagged argument values on the side and materialize the |
+ // actual arguments object after the deoptimized frame is built. |
+ for (int i = 0; i < args_length; i++) { |
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(args_index + i); |
+ intptr_t input_value = args_known |
+ ? input_->GetFrameSlot(input_offset) |
+ : reinterpret_cast<intptr_t>(isolate_->heap()->the_hole_value()); |
+ AddArgumentsObjectValue(input_value); |
} |
return; |
} |
@@ -2522,22 +2324,15 @@ Object* Deoptimizer::ComputeLiteral(int index) const { |
} |
-void Deoptimizer::AddObjectStart(intptr_t slot_address, int length) { |
- ObjectMaterializationDescriptor object_desc( |
- reinterpret_cast<Address>(slot_address), length); |
- deferred_objects_.Add(object_desc); |
+void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) { |
+ ArgumentsObjectMaterializationDescriptor object_desc( |
+ reinterpret_cast<Address>(slot_address), argc); |
+ deferred_arguments_objects_.Add(object_desc); |
} |
-void Deoptimizer::AddObjectTaggedValue(intptr_t value) { |
- deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value)); |
- deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value()); |
-} |
- |
- |
-void Deoptimizer::AddObjectDoubleValue(double value) { |
- deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value()); |
- deferred_objects_double_values_.Add(value); |
+void Deoptimizer::AddArgumentsObjectValue(intptr_t value) { |
+ deferred_arguments_objects_values_.Add(reinterpret_cast<Object*>(value)); |
} |
@@ -2761,12 +2556,6 @@ void Translation::BeginCompiledStubFrame() { |
} |
-void Translation::BeginArgumentsObject(int args_length) { |
- buffer_->Add(ARGUMENTS_OBJECT, zone()); |
- buffer_->Add(args_length, zone()); |
-} |
- |
- |
void Translation::StoreRegister(Register reg) { |
buffer_->Add(REGISTER, zone()); |
buffer_->Add(reg.code(), zone()); |
@@ -2821,6 +2610,16 @@ void Translation::StoreLiteral(int literal_id) { |
} |
+void Translation::StoreArgumentsObject(bool args_known, |
+ int args_index, |
+ int args_length) { |
+ buffer_->Add(ARGUMENTS_OBJECT, zone()); |
+ buffer_->Add(args_known, zone()); |
+ buffer_->Add(args_index, zone()); |
+ buffer_->Add(args_length, zone()); |
+} |
+ |
+ |
void Translation::MarkDuplicate() { |
buffer_->Add(DUPLICATE, zone()); |
} |
@@ -2832,7 +2631,6 @@ int Translation::NumberOfOperandsFor(Opcode opcode) { |
return 0; |
case GETTER_STUB_FRAME: |
case SETTER_STUB_FRAME: |
- case ARGUMENTS_OBJECT: |
case REGISTER: |
case INT32_REGISTER: |
case UINT32_REGISTER: |
@@ -2849,6 +2647,7 @@ int Translation::NumberOfOperandsFor(Opcode opcode) { |
case CONSTRUCT_STUB_FRAME: |
return 2; |
case JS_FRAME: |
+ case ARGUMENTS_OBJECT: |
return 3; |
} |
UNREACHABLE(); |