Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Unified Diff: src/deoptimizer.cc

Issue 16779004: Allow the deoptimizer translation to track de-materialized objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Improved comments slightly. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | src/hydrogen.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 723d3f692e6b3e45e415534d20d21e1eb977ee03..14c1d730d01d6f7b5f8e27b314ec463a9d210443 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -534,8 +534,9 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
output_count_(0),
jsframe_count_(0),
output_(NULL),
- deferred_arguments_objects_values_(0),
- deferred_arguments_objects_(0),
+ deferred_objects_tagged_values_(0),
+ deferred_objects_double_values_(0),
+ deferred_objects_(0),
deferred_heap_numbers_(0),
trace_(false) {
// For COMPILED_STUBs called from builtins, the function pointer is a SMI
@@ -1566,15 +1567,14 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
ASSERT_NE(DEBUGGER, bailout_type_);
- // 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_));
+ // 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_));
}
// Play it safe and clear all unhandlified values before we continue.
- deferred_arguments_objects_values_.Clear();
+ deferred_objects_tagged_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,6 +1591,18 @@ 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();
@@ -1599,9 +1611,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()) {
- ArgumentsObjectMaterializationDescriptor descriptor =
- deferred_arguments_objects_.RemoveLast();
- const int length = descriptor.arguments_length();
+ ObjectMaterializationDescriptor descriptor =
+ deferred_objects_.RemoveLast();
+ const int length = descriptor.object_length();
if (arguments.is_null()) {
if (frame->has_adapted_arguments()) {
// Use the arguments adapter frame we just built to materialize the
@@ -1695,7 +1707,7 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
#endif
-static const char* TraceValueType(bool is_smi, bool is_native) {
+static const char* TraceValueType(bool is_smi, bool is_native = false) {
if (is_native) {
return "native";
} else if (is_smi) {
@@ -1706,6 +1718,204 @@ static const char* TraceValueType(bool is_smi, bool is_native) {
}
+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,
@@ -1758,7 +1968,6 @@ 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",
@@ -1836,8 +2045,7 @@ 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 ": ",
@@ -1855,8 +2063,7 @@ 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);
@@ -1888,8 +2095,7 @@ 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) &&
@@ -1922,8 +2128,7 @@ 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",
@@ -1954,31 +2159,24 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
}
case Translation::ARGUMENTS_OBJECT: {
- bool args_known = iterator->Next();
- int args_index = iterator->Next() + 1; // Skip receiver.
- int args_length = iterator->Next() - 1; // Skip receiver.
+ int length = iterator->Next();
if (trace_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ",
output_[frame_index]->GetTop() + output_offset,
output_offset);
isolate_->heap()->arguments_marker()->ShortPrint();
- PrintF(" ; %sarguments object\n", args_known ? "" : "dummy ");
+ PrintF(" ; arguments object (length = %d)\n", length);
}
// 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());
- AddArgumentsObject(
- output_[frame_index]->GetTop() + output_offset, args_length);
+ AddObjectStart(output_[frame_index]->GetTop() + output_offset, length);
output_[frame_index]->SetFrameSlot(output_offset, value);
- // 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);
+ // 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);
}
return;
}
@@ -2324,15 +2522,22 @@ Object* Deoptimizer::ComputeLiteral(int index) const {
}
-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::AddObjectStart(intptr_t slot_address, int length) {
+ ObjectMaterializationDescriptor object_desc(
+ reinterpret_cast<Address>(slot_address), length);
+ deferred_objects_.Add(object_desc);
}
-void Deoptimizer::AddArgumentsObjectValue(intptr_t value) {
- deferred_arguments_objects_values_.Add(reinterpret_cast<Object*>(value));
+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);
}
@@ -2556,6 +2761,12 @@ 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());
@@ -2610,16 +2821,6 @@ 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());
}
@@ -2631,6 +2832,7 @@ 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:
@@ -2647,7 +2849,6 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case CONSTRUCT_STUB_FRAME:
return 2;
case JS_FRAME:
- case ARGUMENTS_OBJECT:
return 3;
}
UNREACHABLE();
« no previous file with comments | « src/deoptimizer.h ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698