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

Unified Diff: src/deoptimizer.cc

Issue 1169103004: [deoptimizer] Basic support inlining based on SharedFunctionInfo. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Jaros comment. Created 5 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/frames.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 a6778100a4426990780b8bde0e3aef3399f92a6b..a194db7f78492845d9fe2091fa1e72a6460c3899 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -832,10 +832,11 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
int input_index = 0;
BailoutId node_id = translated_frame->node_id();
- JSFunction* function = translated_frame->raw_function();
unsigned height =
translated_frame->height() - 1; // Do not count the context.
unsigned height_in_bytes = height * kPointerSize;
+ JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
+ value_iterator++;
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(), " translating frame ");
function->PrintName(trace_scope_->file());
@@ -1071,9 +1072,10 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
TranslatedFrame::iterator value_iterator = translated_frame->begin();
int input_index = 0;
- JSFunction* function = translated_frame->raw_function();
unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize;
+ JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
+ value_iterator++;
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
" translating arguments adaptor => height=%d\n", height_in_bytes);
@@ -1203,9 +1205,10 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
Builtins* builtins = isolate_->builtins();
Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
- JSFunction* function = translated_frame->raw_function();
unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize;
+ JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
+ value_iterator++;
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
" translating construct stub => height=%d\n", height_in_bytes);
@@ -1371,7 +1374,8 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
TranslatedFrame::iterator value_iterator = translated_frame->begin();
int input_index = 0;
- JSFunction* accessor = translated_frame->raw_function();
+ JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue());
+ value_iterator++;
// The receiver (and the implicit return value, if any) are expected in
// registers by the LoadIC/StoreIC, so they don't belong to the output stack
// frame. This means that we have to use a height of 0.
@@ -1812,8 +1816,7 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
TranslatedFrame* frame = &(translated_state_.frames()[frame_index]);
CHECK(frame->kind() == TranslatedFrame::kFunction);
- int frame_arg_count =
- frame->function()->shared()->internal_formal_parameter_count();
+ int frame_arg_count = frame->shared_info()->internal_formal_parameter_count();
// The height is #expressions + 1 for context.
CHECK_EQ(expression_count + 1, frame->height());
@@ -1832,6 +1835,7 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
}
TranslatedFrame::iterator arg_iter = argument_frame->begin();
+ arg_iter++; // Skip the function.
arg_iter++; // Skip the receiver.
for (int i = 0; i < parameter_count; i++, arg_iter++) {
if (!arg_iter->IsMaterializedObject()) {
@@ -1840,8 +1844,8 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
}
TranslatedFrame::iterator iter = frame->begin();
- // Skip the arguments, receiver and context.
- for (int i = 0; i < frame_arg_count + 2; i++, iter++) {
+ // Skip the function, receiver, context and arguments.
+ for (int i = 0; i < frame_arg_count + 3; i++, iter++) {
}
for (int i = 0; i < expression_count; i++, iter++) {
@@ -2236,8 +2240,15 @@ void Translation::StoreArgumentsObject(bool args_known,
}
+void Translation::StoreJSFrameFunction() {
+ buffer_->Add(JS_FRAME_FUNCTION, zone());
+}
+
+
int Translation::NumberOfOperandsFor(Opcode opcode) {
switch (opcode) {
+ case JS_FRAME_FUNCTION:
+ return 0;
case GETTER_STUB_FRAME:
case SETTER_STUB_FRAME:
case DUPLICATED_OBJECT:
@@ -2741,30 +2752,32 @@ void TranslatedValue::Handlify() {
TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
- JSFunction* function, int height) {
- TranslatedFrame frame(kFunction, function->GetIsolate(), function, height);
+ SharedFunctionInfo* shared_info,
+ int height) {
+ TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
+ height);
frame.node_id_ = node_id;
return frame;
}
-TranslatedFrame TranslatedFrame::AccessorFrame(Kind kind,
- JSFunction* function) {
+TranslatedFrame TranslatedFrame::AccessorFrame(
+ Kind kind, SharedFunctionInfo* shared_info) {
DCHECK(kind == kSetter || kind == kGetter);
- return TranslatedFrame(kind, function->GetIsolate(), function);
+ return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info);
}
-TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(JSFunction* function,
- int height) {
- return TranslatedFrame(kArgumentsAdaptor, function->GetIsolate(), function,
- height);
+TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(
+ SharedFunctionInfo* shared_info, int height) {
+ return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(),
+ shared_info, height);
}
-TranslatedFrame TranslatedFrame::ConstructStubFrame(JSFunction* function,
- int height) {
- return TranslatedFrame(kConstructStub, function->GetIsolate(), function,
+TranslatedFrame TranslatedFrame::ConstructStubFrame(
+ SharedFunctionInfo* shared_info, int height) {
+ return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info,
height);
}
@@ -2773,21 +2786,20 @@ int TranslatedFrame::GetValueCount() {
switch (kind()) {
case kFunction: {
int parameter_count =
- (raw_function_ == nullptr
- ? function_->shared()->internal_formal_parameter_count()
- : raw_function_->shared()->internal_formal_parameter_count()) +
- 1;
- return height_ + parameter_count;
+ raw_shared_info_->internal_formal_parameter_count() + 1;
+ return height_ + parameter_count + 1;
}
case kGetter:
- return 1; // Receiver.
+ return 2; // Function and receiver.
case kSetter:
- return 2; // Receiver and the value to set.
+ return 3; // Function, receiver and the value to set.
case kArgumentsAdaptor:
case kConstructStub:
+ return 1 + height_;
+
case kCompiledStub:
return height_;
@@ -2800,10 +2812,10 @@ int TranslatedFrame::GetValueCount() {
}
-void TranslatedFrame::Handlify(Isolate* isolate) {
- if (raw_function_ != nullptr) {
- function_ = Handle<JSFunction>(raw_function_, isolate);
- raw_function_ = nullptr;
+void TranslatedFrame::Handlify() {
+ if (raw_shared_info_ != nullptr) {
+ shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_);
+ raw_shared_info_ = nullptr;
}
for (auto& value : values_) {
value.Handlify();
@@ -2819,67 +2831,63 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
switch (opcode) {
case Translation::JS_FRAME: {
BailoutId node_id = BailoutId(iterator->Next());
- int closure_id = iterator->Next();
- JSFunction* function =
- (closure_id == Translation::kSelfLiteralId)
- ? frame_function
- : JSFunction::cast(literal_array->get(closure_id));
+ SharedFunctionInfo* shared_info =
+ SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
int height = iterator->Next();
if (trace_file != nullptr) {
- PrintF(trace_file, " reading input frame ");
- function->PrintName(trace_file);
- int arg_count =
- function->shared()->internal_formal_parameter_count() + 1;
+ SmartArrayPointer<char> name = shared_info->DebugName()->ToCString();
+ PrintF(trace_file, " reading input frame %s", name.get());
+ int arg_count = shared_info->internal_formal_parameter_count() + 1;
PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n",
arg_count, node_id.ToInt(), height);
}
- return TranslatedFrame::JSFrame(node_id, function, height);
+ return TranslatedFrame::JSFrame(node_id, shared_info, height);
}
case Translation::ARGUMENTS_ADAPTOR_FRAME: {
- JSFunction* function =
- JSFunction::cast(literal_array->get(iterator->Next()));
+ SharedFunctionInfo* shared_info =
+ SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
int height = iterator->Next();
if (trace_file != nullptr) {
- PrintF(trace_file, " reading arguments adaptor frame");
- function->PrintName(trace_file);
+ SmartArrayPointer<char> name = shared_info->DebugName()->ToCString();
+ PrintF(trace_file, " reading arguments adaptor frame %s", name.get());
PrintF(trace_file, " => height=%d; inputs:\n", height);
}
- return TranslatedFrame::ArgumentsAdaptorFrame(function, height);
+ return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
}
case Translation::CONSTRUCT_STUB_FRAME: {
- JSFunction* function =
- JSFunction::cast(literal_array->get(iterator->Next()));
+ SharedFunctionInfo* shared_info =
+ SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
int height = iterator->Next();
if (trace_file != nullptr) {
- PrintF(trace_file, " reading construct stub frame ");
- function->PrintName(trace_file);
+ SmartArrayPointer<char> name = shared_info->DebugName()->ToCString();
+ PrintF(trace_file, " reading construct stub frame %s", name.get());
PrintF(trace_file, " => height=%d; inputs:\n", height);
}
- return TranslatedFrame::ConstructStubFrame(function, height);
+ return TranslatedFrame::ConstructStubFrame(shared_info, height);
}
case Translation::GETTER_STUB_FRAME: {
- JSFunction* function =
- JSFunction::cast(literal_array->get(iterator->Next()));
+ SharedFunctionInfo* shared_info =
+ SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
if (trace_file != nullptr) {
- PrintF(trace_file, " reading getter frame ");
- function->PrintName(trace_file);
- PrintF(trace_file, "; inputs:\n");
+ SmartArrayPointer<char> name = shared_info->DebugName()->ToCString();
+ PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get());
}
- return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, function);
+ return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter,
+ shared_info);
}
case Translation::SETTER_STUB_FRAME: {
- JSFunction* function =
- JSFunction::cast(literal_array->get(iterator->Next()));
+ SharedFunctionInfo* shared_info =
+ SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
if (trace_file != nullptr) {
- PrintF(trace_file, " reading setter frame ");
- function->PrintName(trace_file);
- PrintF(trace_file, "; inputs:\n");
+ SmartArrayPointer<char> name = shared_info->DebugName()->ToCString();
+ PrintF(trace_file, " reading setter frame %s; inputs:\n", name.get());
}
- return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter, function);
+ return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter,
+ shared_info);
}
case Translation::COMPILED_STUB_FRAME: {
@@ -2907,6 +2915,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
case Translation::BOOL_STACK_SLOT:
case Translation::DOUBLE_STACK_SLOT:
case Translation::LITERAL:
+ case Translation::JS_FRAME_FUNCTION:
break;
}
FATAL("We should never get here - unexpected deopt info.");
@@ -3103,6 +3112,16 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
return TranslatedValue::NewTagged(this, value);
}
+
+ case Translation::JS_FRAME_FUNCTION: {
+ int slot_offset = JavaScriptFrameConstants::kFunctionOffset;
+ intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
+ if (trace_file != nullptr) {
+ PrintF(trace_file, "0x%08" V8PRIxPTR " ; (frame function) ", value);
+ reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
+ }
+ return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
+ }
}
FATAL("We should never get here - unexpected deopt info.");
@@ -3207,9 +3226,7 @@ void TranslatedState::Init(Address input_frame_pointer,
void TranslatedState::Prepare(bool has_adapted_arguments,
Address stack_frame_pointer) {
- for (auto& frame : frames_) {
- frame.Handlify(isolate_);
- }
+ for (auto& frame : frames_) frame.Handlify();
stack_frame_pointer_ = stack_frame_pointer;
has_adapted_arguments_ = has_adapted_arguments;
@@ -3249,7 +3266,8 @@ Handle<Object> TranslatedState::MaterializeAt(int frame_index,
MaterializeAt(frame_index, value_index);
}
} else {
- Handle<JSFunction> function = frame->function();
+ Handle<JSFunction> function =
+ Handle<JSFunction>::cast(frame->front().GetValue());
arguments = isolate_->factory()->NewArgumentsObject(function, length);
Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
DCHECK_EQ(array->length(), length);
@@ -3380,7 +3398,8 @@ bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
// This is top level frame, so we need to go to the stack to get
// this function's argument. (Note that this relies on not inlining
// recursive functions!)
- Handle<JSFunction> function = frames_[frame_index].function();
+ Handle<JSFunction> function =
+ Handle<JSFunction>::cast(frames_[frame_index].front().GetValue());
*result = Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
return true;
} else {
@@ -3389,13 +3408,15 @@ bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
return false;
}
// We get the adapted arguments from the parent translation.
- int length = previous_frame->GetValueCount();
- Handle<JSFunction> function = previous_frame->function();
+ int length = previous_frame->height();
+ Handle<JSFunction> function =
+ Handle<JSFunction>::cast(previous_frame->front().GetValue());
Handle<JSObject> arguments =
isolate_->factory()->NewArgumentsObject(function, length);
Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
arguments->set_elements(*array);
TranslatedFrame::iterator arg_iterator = previous_frame->begin();
+ arg_iterator++; // Skip function.
for (int i = 0; i < length; ++i) {
Handle<Object> value = arg_iterator->GetValue();
array->set(i, *value);
@@ -3422,8 +3443,7 @@ TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
return &(frames_[i - 1]);
}
*args_count =
- frames_[i].function()->shared()->internal_formal_parameter_count() +
- 1;
+ frames_[i].shared_info()->internal_formal_parameter_count() + 1;
return &(frames_[i]);
}
}
@@ -3475,8 +3495,9 @@ void TranslatedState::StoreMaterializedValuesAndDeopt() {
if (new_store && value_changed) {
materialized_store->Set(stack_frame_pointer_,
previously_materialized_objects);
- DCHECK(frames_[0].kind() == TranslatedFrame::kFunction);
- Deoptimizer::DeoptimizeFunction(*(frames_[0].function()));
+ DCHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind());
+ Object* const function = frames_[0].front().GetRawValue();
+ Deoptimizer::DeoptimizeFunction(JSFunction::cast(function));
}
}
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698