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