[deoptimizer] Remove support for full-codegen frames.

This removes support for reconstructing stack frames for full-codegen
from the deoptimizer. We no longer deoptimize to such code. This also
allows us to remove the {DeoptimizationOutputData} data structure.

R=jarin@chromium.org
BUG=v8:6409

Change-Id: Id28ef05aa985b6877b5c91926a7d7d0d6d6e661d
Reviewed-on: https://chromium-review.googlesource.com/535537
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45943}
This commit is contained in:
Michael Starzinger 2017-06-14 13:21:43 +02:00 committed by Commit Bot
parent dfb453d713
commit b5f16bba2a
19 changed files with 23 additions and 560 deletions

View File

@ -285,10 +285,7 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
input_buffer_(nullptr),
exit_controls_(local_zone),
loop_assignment_analysis_(loop),
state_values_cache_(jsgraph),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
info->scope()->num_stack_slots(), info->shared_info())) {
state_values_cache_(jsgraph) {
InitializeAstVisitor(info->isolate());
}

View File

@ -113,9 +113,6 @@ class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
// Cache for StateValues nodes for frame states.
StateValuesCache state_values_cache_;
// Function info for frame state construction.
const FrameStateFunctionInfo* const frame_state_function_info_;
// Growth increment for the temporary buffer used to construct input lists to
// new nodes.
static const int kInputBufferSizeIncrement = 64;
@ -136,9 +133,6 @@ class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
ZoneVector<Handle<Object>>* globals() { return &globals_; }
Scope* current_scope() const;
Node* current_context() const;
const FrameStateFunctionInfo* frame_state_function_info() const {
return frame_state_function_info_;
}
void set_environment(Environment* env) { environment_ = env; }
void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }

View File

@ -788,12 +788,6 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
DefineDeoptimizationLiteral(DeoptimizationLiteral(shared_info));
switch (descriptor->type()) {
case FrameStateType::kJavaScriptFunction:
translation->BeginJSFrame(
descriptor->bailout_id(), shared_info_id,
static_cast<unsigned int>(descriptor->GetSize(state_combine) -
(1 + descriptor->parameters_count())));
break;
case FrameStateType::kInterpretedFunction:
translation->BeginInterpretedFrame(
descriptor->bailout_id(), shared_info_id,

View File

@ -53,9 +53,6 @@ size_t hash_value(FrameStateInfo const& info) {
std::ostream& operator<<(std::ostream& os, FrameStateType type) {
switch (type) {
case FrameStateType::kJavaScriptFunction:
os << "JS_FRAME";
break;
case FrameStateType::kInterpretedFunction:
os << "INTERPRETED_FRAME";
break;

View File

@ -78,7 +78,6 @@ class OutputFrameStateCombine {
// The type of stack frame that a FrameState node represents.
enum class FrameStateType {
kJavaScriptFunction, // Represents an unoptimized JavaScriptFrame.
kInterpretedFunction, // Represents an InterpretedFrame.
kArgumentsAdaptor, // Represents an ArgumentsAdaptorFrame.
kTailCallerFunction, // Represents a frame removed by tail call elimination.
@ -106,8 +105,7 @@ class FrameStateFunctionInfo {
FrameStateType type() const { return type_; }
static bool IsJSFunctionType(FrameStateType type) {
return type == FrameStateType::kJavaScriptFunction ||
type == FrameStateType::kInterpretedFunction ||
return type == FrameStateType::kInterpretedFunction ||
type == FrameStateType::kJavaScriptBuiltinContinuation;
}
@ -128,7 +126,7 @@ class FrameStateInfo final {
info_(info) {}
FrameStateType type() const {
return info_ == nullptr ? FrameStateType::kJavaScriptFunction
return info_ == nullptr ? FrameStateType::kInterpretedFunction
: info_->type();
}
BailoutId bailout_id() const { return bailout_id_; }

View File

@ -1382,7 +1382,7 @@ JSNativeContextSpecialization::BuildPropertyAccess(
switch (access_mode) {
case AccessMode::kLoad: {
// We need a FrameState for the getter stub to restore the correct
// context before returning to fullcodegen.
// context before returning to unoptimized code.
FrameStateFunctionInfo const* frame_info0 =
common()->CreateFrameStateFunctionInfo(FrameStateType::kGetterStub,
1, 0, shared_info);
@ -1417,7 +1417,7 @@ JSNativeContextSpecialization::BuildPropertyAccess(
}
case AccessMode::kStore: {
// We need a FrameState for the setter stub to restore the correct
// context and return the appropriate value to fullcodegen.
// context and return the appropriate value to unoptimized code.
FrameStateFunctionInfo const* frame_info0 =
common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub,
2, 0, shared_info);

View File

@ -348,9 +348,7 @@ HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
RemovableSimulate removable) {
DCHECK(HasEnvironment());
HEnvironment* environment = last_environment();
DCHECK(ast_id.IsNone() ||
ast_id == BailoutId::StubEntry() ||
environment->closure()->shared()->VerifyBailoutId(ast_id));
DCHECK(ast_id.IsNone() || ast_id == BailoutId::StubEntry());
int push_count = environment->push_count();
int pop_count = environment->pop_count();
@ -447,10 +445,6 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) {
HBasicBlock* predecessor = predecessors_[i];
DCHECK(predecessor->end()->IsGoto());
HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
DCHECK(i != 0 ||
(predecessor->last_environment()->closure().is_null() ||
predecessor->last_environment()->closure()->shared()
->VerifyBailoutId(ast_id)));
simulate->set_ast_id(ast_id);
predecessor->last_environment()->set_ast_id(ast_id);
}

View File

@ -220,21 +220,14 @@ int LCodeGenBase::DefineDeoptimizationLiteral(Handle<Object> literal) {
void LCodeGenBase::WriteTranslationFrame(LEnvironment* environment,
Translation* translation) {
int translation_size = environment->translation_size();
#ifdef DEBUG
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
#endif // DEBUG
switch (environment->frame_type()) {
case JS_FUNCTION: {
int shared_id = DefineDeoptimizationLiteral(
environment->entry() ? environment->entry()->shared()
: info()->shared_info());
translation->BeginJSFrame(environment->ast_id(), shared_id, height);
if (info()->closure().is_identical_to(environment->closure())) {
translation->StoreJSFrameFunction();
} else {
int closure_id = DefineDeoptimizationLiteral(environment->closure());
translation->StoreLiteral(closure_id);
}
UNREACHABLE();
break;
}
case JS_CONSTRUCT: {

View File

@ -117,8 +117,7 @@ DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
int counter = jsframe_index;
for (auto it = translated_values.begin(); it != translated_values.end();
it++) {
if (it->kind() == TranslatedFrame::kFunction ||
it->kind() == TranslatedFrame::kInterpretedFunction) {
if (it->kind() == TranslatedFrame::kInterpretedFunction) {
if (counter == 0) {
frame_it = it;
break;
@ -630,30 +629,6 @@ int Deoptimizer::GetDeoptimizationId(Isolate* isolate,
}
int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
BailoutId id,
SharedFunctionInfo* shared) {
// TODO(kasperl): For now, we do a simple linear search for the PC
// offset associated with the given node id. This should probably be
// changed to a binary search.
int length = data->DeoptPoints();
for (int i = 0; i < length; i++) {
if (data->AstId(i) == id) {
return data->PcAndState(i)->value();
}
}
OFStream os(stderr);
os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
<< "[method: " << shared->DebugName()->ToCString().get() << "]\n"
<< "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
shared->GetHeap()->isolate()->PushStackTraceAndDie(0xfefefefe, data, shared,
0xfefefeff);
FATAL("unable to find pc offset during deoptimization");
return -1;
}
int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
int length = 0;
// Count all entries in the deoptimizing code list of every context.
@ -676,17 +651,6 @@ namespace {
int LookupCatchHandler(TranslatedFrame* translated_frame, int* data_out) {
switch (translated_frame->kind()) {
case TranslatedFrame::kFunction: {
#ifdef DEBUG
JSFunction* function =
JSFunction::cast(translated_frame->begin()->GetRawValue());
Code* non_optimized_code = function->shared()->code();
HandlerTable* table =
HandlerTable::cast(non_optimized_code->handler_table());
DCHECK_EQ(0, table->NumberOfRangeEntries());
#endif
break;
}
case TranslatedFrame::kInterpretedFunction: {
int bytecode_offset = translated_frame->node_id().ToInt();
JSFunction* function =
@ -796,11 +760,6 @@ void Deoptimizer::DoComputeOutputFrames() {
// Read the ast node id, function, and frame height for this output frame.
TranslatedFrame* translated_frame = &(translated_state_.frames()[i]);
switch (translated_frame->kind()) {
case TranslatedFrame::kFunction:
DoComputeJSFrame(translated_frame, frame_index,
deoptimizing_throw_ && i == count - 1);
jsframe_count_++;
break;
case TranslatedFrame::kInterpretedFunction:
DoComputeInterpretedFrame(translated_frame, frame_index,
deoptimizing_throw_ && i == count - 1);
@ -856,248 +815,6 @@ void Deoptimizer::DoComputeOutputFrames() {
}
}
void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
int frame_index, bool goto_catch_handler) {
SharedFunctionInfo* shared = translated_frame->raw_shared_info();
TranslatedFrame::iterator value_iterator = translated_frame->begin();
bool is_bottommost = (0 == frame_index);
bool is_topmost = (output_count_ - 1 == frame_index);
int input_index = 0;
BailoutId node_id = translated_frame->node_id();
unsigned height =
translated_frame->height() - 1; // Do not count the context.
unsigned height_in_bytes = height * kPointerSize;
if (goto_catch_handler) {
// Take the stack height from the handler table.
height = catch_handler_data_;
// We also make space for the exception itself.
height_in_bytes = (height + 1) * kPointerSize;
CHECK(is_topmost);
}
JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
value_iterator++;
input_index++;
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(), " translating frame ");
std::unique_ptr<char[]> name = shared->DebugName()->ToCString();
PrintF(trace_scope_->file(), "%s", name.get());
PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(),
height_in_bytes, goto_catch_handler ? " (throw)" : "");
}
// The 'fixed' part of the frame consists of the incoming parameters and
// the part described by JavaScriptFrameConstants.
unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
int parameter_count = shared->internal_formal_parameter_count() + 1;
FrameDescription* output_frame = new (output_frame_size)
FrameDescription(output_frame_size, parameter_count);
output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
CHECK(frame_index >= 0 && frame_index < output_count_);
CHECK_NULL(output_[frame_index]);
output_[frame_index] = output_frame;
// The top address of the frame is computed from the previous frame's top and
// this frame's size.
intptr_t top_address;
if (is_bottommost) {
top_address = caller_frame_top_ - output_frame_size;
} else {
top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
}
output_frame->SetTop(top_address);
// Compute the incoming parameter translation.
unsigned output_offset = output_frame_size;
for (int i = 0; i < parameter_count; ++i) {
output_offset -= kPointerSize;
WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
output_offset);
}
if (trace_scope_ != nullptr) {
PrintF(trace_scope_->file(), " -------------------------\n");
}
// There are no translation commands for the caller's pc and fp, the
// context, and the function. Synthesize their values and set them up
// explicitly.
//
// The caller's pc for the bottommost output frame is the same as in the
// input frame. For all subsequent output frames, it can be read from the
// previous one. This frame's pc can be computed from the non-optimized
// function code and AST id of the bailout.
output_offset -= kPCOnStackSize;
intptr_t value;
if (is_bottommost) {
value = caller_pc_;
} else {
value = output_[frame_index - 1]->GetPc();
}
output_frame->SetCallerPc(output_offset, value);
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n");
// The caller's frame pointer for the bottommost output frame is the same
// as in the input frame. For all subsequent output frames, it can be
// read from the previous one. Also compute and set this frame's frame
// pointer.
output_offset -= kFPOnStackSize;
if (is_bottommost) {
value = caller_fp_;
} else {
value = output_[frame_index - 1]->GetFp();
}
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
output_frame->SetFp(fp_value);
if (is_topmost) {
Register fp_reg = JavaScriptFrame::fp_register();
output_frame->SetRegister(fp_reg.code(), fp_value);
}
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
if (FLAG_enable_embedded_constant_pool) {
// For the bottommost output frame the constant pool pointer can be gotten
// from the input frame. For subsequent output frames, it can be read from
// the previous frame.
output_offset -= kPointerSize;
if (is_bottommost) {
value = caller_constant_pool_;
} else {
value = output_[frame_index - 1]->GetConstantPool();
}
output_frame->SetCallerConstantPool(output_offset, value);
DebugPrintOutputSlot(value, frame_index, output_offset,
"caller's constant_pool\n");
}
// For the bottommost output frame the context can be gotten from the input
// frame. For all subsequent output frames it can be gotten from the function
// so long as we don't inline functions that need local contexts.
output_offset -= kPointerSize;
// When deoptimizing into a catch block, we need to take the context
// from just above the top of the operand stack (we push the context
// at the entry of the try block).
TranslatedFrame::iterator context_pos = value_iterator;
int context_input_index = input_index;
if (goto_catch_handler) {
for (unsigned i = 0; i < height + 1; ++i) {
context_pos++;
context_input_index++;
}
}
// Read the context from the translations.
Object* context = context_pos->GetRawValue();
if (context->IsUndefined(isolate_)) {
// If the context was optimized away, just use the context from
// the activation. This should only apply to Crankshaft code.
CHECK(!compiled_code_->is_turbofanned());
context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
: function->context();
}
value = reinterpret_cast<intptr_t>(context);
output_frame->SetContext(value);
WriteValueToOutput(context, context_input_index, frame_index, output_offset,
"context ");
if (context == isolate_->heap()->arguments_marker()) {
Address output_address =
reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
output_offset;
values_to_materialize_.push_back({output_address, context_pos});
}
value_iterator++;
input_index++;
// The function was mentioned explicitly in the BEGIN_FRAME.
output_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(function);
WriteValueToOutput(function, 0, frame_index, output_offset, "function ");
if (trace_scope_ != nullptr) {
PrintF(trace_scope_->file(), " -------------------------\n");
}
// Translate the rest of the frame.
for (unsigned i = 0; i < height; ++i) {
output_offset -= kPointerSize;
WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
output_offset);
}
if (goto_catch_handler) {
// Write out the exception for the catch handler.
output_offset -= kPointerSize;
Object* exception_obj = reinterpret_cast<Object*>(
input_->GetRegister(FullCodeGenerator::result_register().code()));
WriteValueToOutput(exception_obj, input_index, frame_index, output_offset,
"exception ");
input_index++;
}
CHECK_EQ(0u, output_offset);
// Update constant pool.
Code* non_optimized_code = shared->code();
if (FLAG_enable_embedded_constant_pool) {
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
if (is_topmost) {
Register constant_pool_reg =
JavaScriptFrame::constant_pool_pointer_register();
output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
}
}
// Compute this frame's PC and state.
FixedArray* raw_data = non_optimized_code->deoptimization_data();
DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
Address start = non_optimized_code->instruction_start();
unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
unsigned pc_offset = goto_catch_handler
? catch_handler_pc_offset_
: FullCodeGenerator::PcField::decode(pc_and_state);
intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
output_frame->SetPc(pc_value);
// If we are going to the catch handler, then the exception lives in
// the accumulator.
BailoutState state =
goto_catch_handler
? BailoutState::TOS_REGISTER
: FullCodeGenerator::BailoutStateField::decode(pc_and_state);
output_frame->SetState(Smi::FromInt(static_cast<int>(state)));
// Clear the context register. The context might be a de-materialized object
// and will be materialized by {Runtime_NotifyDeoptimized}. For additional
// safety we use Smi(0) instead of the potential {arguments_marker} here.
if (is_topmost) {
intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
Register context_reg = JavaScriptFrame::context_register();
output_frame->SetRegister(context_reg.code(), context_value);
}
// Set the continuation for the topmost frame.
if (is_topmost) {
Builtins* builtins = isolate_->builtins();
Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
if (bailout_type_ == LAZY) {
continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
} else if (bailout_type_ == SOFT) {
continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
} else {
CHECK_EQ(bailout_type_, EAGER);
}
output_frame->SetContinuation(
reinterpret_cast<intptr_t>(continuation->entry()));
}
}
void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
int frame_index,
bool goto_catch_handler) {
@ -2747,15 +2464,6 @@ void Translation::BeginTailCallerFrame(int literal_id) {
buffer_->Add(literal_id);
}
void Translation::BeginJSFrame(BailoutId node_id, int literal_id,
unsigned height) {
buffer_->Add(JS_FRAME);
buffer_->Add(node_id.ToInt());
buffer_->Add(literal_id);
buffer_->Add(height);
}
void Translation::BeginInterpretedFrame(BailoutId bytecode_offset,
int literal_id, unsigned height) {
buffer_->Add(INTERPRETED_FRAME);
@ -2914,7 +2622,6 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case BEGIN:
case ARGUMENTS_ADAPTOR_FRAME:
return 2;
case JS_FRAME:
case INTERPRETED_FRAME:
case CONSTRUCT_STUB_FRAME:
case BUILTIN_CONTINUATION_FRAME:
@ -3064,14 +2771,9 @@ DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
parameter_frame != state->begin() &&
(parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub;
if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
source_position_ = Deoptimizer::ComputeSourcePositionFromBytecodeArray(
*frame_it->shared_info(), frame_it->node_id());
} else {
DCHECK_EQ(TranslatedFrame::kFunction, frame_it->kind());
source_position_ = Deoptimizer::ComputeSourcePositionFromBaselineCode(
*frame_it->shared_info(), frame_it->node_id());
}
DCHECK_EQ(TranslatedFrame::kInterpretedFunction, frame_it->kind());
source_position_ = Deoptimizer::ComputeSourcePositionFromBytecodeArray(
*frame_it->shared_info(), frame_it->node_id());
TranslatedFrame::iterator value_it = frame_it->begin();
// Get the function. Note that this might materialize the function.
@ -3100,9 +2802,7 @@ DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
// Get the expression stack.
int stack_height = frame_it->height();
if (frame_it->kind() == TranslatedFrame::kFunction ||
frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
// For full-code frames, we should not count the context.
if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) {
// For interpreter frames, we should not count the accumulator.
// TODO(jarin): Clean up the indexing in translated frames.
stack_height--;
@ -3150,19 +2850,6 @@ Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
}
// static
int Deoptimizer::ComputeSourcePositionFromBaselineCode(
SharedFunctionInfo* shared, BailoutId node_id) {
DCHECK(shared->HasBaselineCode());
Code* code = shared->code();
FixedArray* raw_data = code->deoptimization_data();
DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared);
int code_offset =
static_cast<int>(FullCodeGenerator::PcField::decode(pc_and_state));
return AbstractCode::cast(code)->SourcePosition(code_offset);
}
// static
int Deoptimizer::ComputeSourcePositionFromBytecodeArray(
SharedFunctionInfo* shared, BailoutId node_id) {
@ -3479,16 +3166,6 @@ void TranslatedValue::Handlify() {
}
TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id,
SharedFunctionInfo* shared_info,
int height) {
TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info,
height);
frame.node_id_ = node_id;
return frame;
}
TranslatedFrame TranslatedFrame::InterpretedFrame(
BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) {
TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(),
@ -3544,13 +3221,6 @@ TranslatedFrame TranslatedFrame::JavaScriptBuiltinContinuationFrame(
int TranslatedFrame::GetValueCount() {
switch (kind()) {
case kFunction: {
int parameter_count =
raw_shared_info_->internal_formal_parameter_count() + 1;
// + 1 for function.
return height_ + parameter_count + 1;
}
case kInterpretedFunction: {
int parameter_count =
raw_shared_info_->internal_formal_parameter_count() + 1;
@ -3601,21 +3271,6 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
Translation::Opcode opcode =
static_cast<Translation::Opcode>(iterator->Next());
switch (opcode) {
case Translation::JS_FRAME: {
BailoutId node_id = BailoutId(iterator->Next());
SharedFunctionInfo* shared_info =
SharedFunctionInfo::cast(literal_array->get(iterator->Next()));
int height = iterator->Next();
if (trace_file != nullptr) {
std::unique_ptr<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",
node_id.ToInt(), arg_count, height);
}
return TranslatedFrame::JSFrame(node_id, shared_info, height);
}
case Translation::INTERPRETED_FRAME: {
BailoutId bytecode_offset = BailoutId(iterator->Next());
SharedFunctionInfo* shared_info =
@ -3863,7 +3518,6 @@ int TranslatedState::CreateNextTranslatedValue(
static_cast<Translation::Opcode>(iterator->Next());
switch (opcode) {
case Translation::BEGIN:
case Translation::JS_FRAME:
case Translation::INTERPRETED_FRAME:
case Translation::ARGUMENTS_ADAPTOR_FRAME:
case Translation::TAIL_CALLER_FRAME:
@ -4769,8 +4423,7 @@ bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
int jsframe_index, int* args_count) {
for (size_t i = 0; i < frames_.size(); i++) {
if (frames_[i].kind() == TranslatedFrame::kFunction ||
frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
if (frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
if (jsframe_index > 0) {
jsframe_index--;
} else {
@ -4833,8 +4486,7 @@ void TranslatedState::StoreMaterializedValuesAndDeopt(JavaScriptFrame* frame) {
if (new_store && value_changed) {
materialized_store->Set(stack_frame_pointer_,
previously_materialized_objects);
CHECK(frames_[0].kind() == TranslatedFrame::kFunction ||
frames_[0].kind() == TranslatedFrame::kInterpretedFunction ||
CHECK(frames_[0].kind() == TranslatedFrame::kInterpretedFunction ||
frames_[0].kind() == TranslatedFrame::kTailCallerFunction);
CHECK_EQ(frame->function(), frames_[0].front().GetRawValue());
Deoptimizer::DeoptimizeFunction(frame->function(), frame->LookupCode());

View File

@ -151,7 +151,6 @@ class TranslatedValue {
class TranslatedFrame {
public:
enum Kind {
kFunction,
kInterpretedFunction,
kGetter,
kSetter,
@ -219,8 +218,6 @@ class TranslatedFrame {
friend class TranslatedState;
// Constructor static methods.
static TranslatedFrame JSFrame(BailoutId node_id,
SharedFunctionInfo* shared_info, int height);
static TranslatedFrame InterpretedFrame(BailoutId bytecode_offset,
SharedFunctionInfo* shared_info,
int height);
@ -395,8 +392,6 @@ class Deoptimizer : public Malloced {
static DeoptInfo GetDeoptInfo(Code* code, byte* from);
static int ComputeSourcePositionFromBaselineCode(SharedFunctionInfo* shared,
BailoutId node_id);
static int ComputeSourcePositionFromBytecodeArray(SharedFunctionInfo* shared,
BailoutId node_id);
@ -498,9 +493,6 @@ class Deoptimizer : public Malloced {
static int GetDeoptimizationId(Isolate* isolate,
Address addr,
BailoutType type);
static int GetOutputInfo(DeoptimizationOutputData* data,
BailoutId node_id,
SharedFunctionInfo* shared);
// Code generation support.
static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
@ -560,8 +552,6 @@ class Deoptimizer : public Malloced {
void DeleteFrameDescriptions();
void DoComputeOutputFrames();
void DoComputeJSFrame(TranslatedFrame* translated_frame, int frame_index,
bool goto_catch_handler);
void DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
int frame_index, bool goto_catch_handler);
void DoComputeArgumentsAdaptorFrame(TranslatedFrame* translated_frame,
@ -931,7 +921,6 @@ class TranslationIterator BASE_EMBEDDED {
#define TRANSLATION_OPCODE_LIST(V) \
V(BEGIN) \
V(JS_FRAME) \
V(INTERPRETED_FRAME) \
V(BUILTIN_CONTINUATION_FRAME) \
V(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) \
@ -982,7 +971,6 @@ class Translation BASE_EMBEDDED {
int index() const { return index_; }
// Commands.
void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
void BeginInterpretedFrame(BailoutId bytecode_offset, int literal_id,
unsigned height);
void BeginCompiledStubFrame(int height);

View File

@ -1386,8 +1386,7 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames,
bool is_constructor = IsConstructor();
while (jsframe_count != 0) {
frame_opcode = static_cast<Translation::Opcode>(it.Next());
if (frame_opcode == Translation::JS_FRAME ||
frame_opcode == Translation::INTERPRETED_FRAME ||
if (frame_opcode == Translation::INTERPRETED_FRAME ||
frame_opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) {
jsframe_count--;
BailoutId const bailout_id = BailoutId(it.Next());
@ -1432,16 +1431,7 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames,
AbstractCode* abstract_code;
unsigned code_offset;
if (frame_opcode == Translation::JS_FRAME) {
Code* code = shared_info->code();
DeoptimizationOutputData* const output_data =
DeoptimizationOutputData::cast(code->deoptimization_data());
unsigned const entry =
Deoptimizer::GetOutputInfo(output_data, bailout_id, shared_info);
code_offset = FullCodeGenerator::PcField::decode(entry);
abstract_code = AbstractCode::cast(code);
} else if (frame_opcode ==
Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) {
if (frame_opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) {
code_offset = 0;
abstract_code = AbstractCode::cast(isolate()->builtins()->builtin(
Builtins::GetBuiltinFromBailoutId(bailout_id)));
@ -1552,8 +1542,7 @@ void OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
// in the deoptimization translation are ordered bottom-to-top.
while (jsframe_count != 0) {
opcode = static_cast<Translation::Opcode>(it.Next());
if (opcode == Translation::JS_FRAME ||
opcode == Translation::INTERPRETED_FRAME ||
if (opcode == Translation::INTERPRETED_FRAME ||
opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) {
it.Next(); // Skip bailout id.
jsframe_count--;

View File

@ -42,11 +42,6 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
static bool MakeCode(CompilationInfo* info, uintptr_t stack_limit);
static bool MakeCode(CompilationInfo* info);
// Encode bailout state and pc-offset as a BitField<type, start, size>.
// Only use 30 bits because we encode the result as a smi.
class BailoutStateField : public BitField<Deoptimizer::BailoutState, 0, 1> {};
class PcField : public BitField<unsigned, 1, 30 - 1> {};
static const int kMaxBackEdgeWeight = 127;
// Platform-specific code size multiplier.

View File

@ -326,15 +326,6 @@ bool HeapObject::IsDeoptimizationInputData() const {
return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
}
bool HeapObject::IsDeoptimizationOutputData() const {
if (!IsFixedArray()) return false;
// There's actually no way to see the difference between a fixed array and
// a deoptimization data array. Since this is used for asserts we can check
// that the length is plausible though.
if (FixedArray::cast(this)->length() % 2 != 0) return false;
return true;
}
bool HeapObject::IsHandlerTable() const {
if (!IsFixedArray()) return false;
// There's actually no way to see the difference between a fixed array and
@ -545,7 +536,6 @@ CAST_ACCESSOR(Code)
CAST_ACCESSOR(ConstantElementsPair)
CAST_ACCESSOR(ContextExtension)
CAST_ACCESSOR(DeoptimizationInputData)
CAST_ACCESSOR(DeoptimizationOutputData)
CAST_ACCESSOR(DependentCode)
CAST_ACCESSOR(DescriptorArray)
CAST_ACCESSOR(FixedArray)
@ -2780,28 +2770,6 @@ int DeoptimizationInputData::DeoptCount() {
}
int DeoptimizationOutputData::DeoptPoints() { return length() / 2; }
BailoutId DeoptimizationOutputData::AstId(int index) {
return BailoutId(Smi::cast(get(index * 2))->value());
}
void DeoptimizationOutputData::SetAstId(int index, BailoutId id) {
set(index * 2, Smi::FromInt(id.ToInt()));
}
Smi* DeoptimizationOutputData::PcAndState(int index) {
return Smi::cast(get(1 + index * 2));
}
void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) {
set(1 + index * 2, offset);
}
int HandlerTable::GetRangeStart(int index) const {
return Smi::cast(get(index * kRangeEntrySize + kRangeStartIndex))->value();
}

View File

@ -10224,20 +10224,6 @@ Handle<DeoptimizationInputData> DeoptimizationInputData::New(
}
Handle<DeoptimizationOutputData> DeoptimizationOutputData::New(
Isolate* isolate,
int number_of_deopt_points,
PretenureFlag pretenure) {
Handle<FixedArray> result;
if (number_of_deopt_points == 0) {
result = isolate->factory()->empty_fixed_array();
} else {
result = isolate->factory()->NewFixedArray(
LengthOfFixedArray(number_of_deopt_points), pretenure);
}
return Handle<DeoptimizationOutputData>::cast(result);
}
SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) {
if (index == -1) {
return SharedFunctionInfo::cast(SharedFunctionInfo());
@ -13599,16 +13585,6 @@ void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
set_expected_nof_properties(estimate);
}
bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) {
DCHECK(!id.IsNone());
Code* unoptimized = code();
DeoptimizationOutputData* data =
DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
USE(ignore);
return true; // Return true if there was no DCHECK.
}
void SharedFunctionInfo::SetConstructStub(Code* code) {
if (code->kind() == Code::BUILTIN) code->set_is_construct_stub(true);
set_construct_stub(code);
@ -14252,17 +14228,6 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
UNREACHABLE();
break;
case Translation::JS_FRAME: {
int ast_id = iterator.Next();
int shared_info_id = iterator.Next();
unsigned height = iterator.Next();
Object* shared_info = LiteralArray()->get(shared_info_id);
os << "{ast_id=" << ast_id << ", function="
<< Brief(SharedFunctionInfo::cast(shared_info)->DebugName())
<< ", height=" << height << "}";
break;
}
case Translation::INTERPRETED_FRAME: {
int bytecode_offset = iterator.Next();
int shared_info_id = iterator.Next();
@ -14440,24 +14405,6 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
}
void DeoptimizationOutputData::DeoptimizationOutputDataPrint(
std::ostream& os) { // NOLINT
os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
<< ")\n";
if (this->DeoptPoints() == 0) return;
os << "ast id pc state\n";
for (int i = 0; i < this->DeoptPoints(); i++) {
int pc_and_state = this->PcAndState(i)->value();
os << std::setw(6) << this->AstId(i).ToInt() << " " << std::setw(8)
<< FullCodeGenerator::PcField::decode(pc_and_state) << " "
<< Deoptimizer::BailoutStateToString(
FullCodeGenerator::BailoutStateField::decode(pc_and_state))
<< "\n";
}
}
void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
os << " from to hdlr\n";
for (int i = 0; i < length(); i += kRangeEntrySize) {
@ -14577,11 +14524,7 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
os << "\n";
}
if (kind() == FUNCTION) {
DeoptimizationOutputData* data =
DeoptimizationOutputData::cast(this->deoptimization_data());
data->DeoptimizationOutputDataPrint(os);
} else if (kind() == OPTIMIZED_FUNCTION) {
if (kind() == OPTIMIZED_FUNCTION) {
DeoptimizationInputData* data =
DeoptimizationInputData::cast(this->deoptimization_data());
data->DeoptimizationInputDataPrint(os);

View File

@ -995,7 +995,6 @@ template <class C> inline bool Is(Object* obj);
V(Context) \
V(CoverageInfo) \
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
V(DependentCode) \
V(DescriptorArray) \
V(Dictionary) \
@ -3516,38 +3515,6 @@ class DeoptimizationInputData: public FixedArray {
static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
};
// DeoptimizationOutputData is a fixed array used to hold the deoptimization
// data for code generated by the full compiler.
// The format of the these objects is
// [i * 2]: Ast ID for ith deoptimization.
// [i * 2 + 1]: PC and state of ith deoptimization
class DeoptimizationOutputData: public FixedArray {
public:
inline int DeoptPoints();
inline BailoutId AstId(int index);
inline void SetAstId(int index, BailoutId id);
inline Smi* PcAndState(int index);
inline void SetPcAndState(int index, Smi* offset);
static int LengthOfFixedArray(int deopt_points) {
return deopt_points * 2;
}
// Allocates a DeoptimizationOutputData.
static Handle<DeoptimizationOutputData> New(Isolate* isolate,
int number_of_deopt_points,
PretenureFlag pretenure);
DECLARE_CAST(DeoptimizationOutputData)
#ifdef ENABLE_DISASSEMBLER
void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
#endif
};
class TemplateList : public FixedArray {
public:
static Handle<TemplateList> New(Isolate* isolate, int size);

View File

@ -328,11 +328,6 @@ class SharedFunctionInfo : public HeapObject {
// shared function info.
void DisableOptimization(BailoutReason reason);
// Lookup the bailout ID and DCHECK that it exists in the non-optimized
// code, returns whether it asserted (i.e., always true if assertions are
// disabled).
bool VerifyBailoutId(BailoutId id);
// [source code]: Source code for the function.
bool HasSourceCode() const;
Handle<Object> GetSourceCode();

View File

@ -220,8 +220,7 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
while (it.HasNext() &&
Translation::BEGIN !=
(opcode = static_cast<Translation::Opcode>(it.Next()))) {
if (opcode != Translation::JS_FRAME &&
opcode != Translation::INTERPRETED_FRAME) {
if (opcode != Translation::INTERPRETED_FRAME) {
it.Skip(Translation::NumberOfOperandsFor(opcode));
continue;
}

View File

@ -149,7 +149,7 @@ const FrameStateFunctionInfo*
InstructionSelectorTest::StreamBuilder::GetFrameStateFunctionInfo(
int parameter_count, int local_count) {
return common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, parameter_count, local_count,
FrameStateType::kInterpretedFunction, parameter_count, local_count,
Handle<SharedFunctionInfo>());
}

View File

@ -53,7 +53,7 @@ class JSCreateLoweringTest : public TypedGraphTest {
common()->FrameState(
BailoutId::None(), OutputFrameStateCombine::Ignore(),
common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, 1, 0, shared)),
FrameStateType::kInterpretedFunction, 1, 0, shared)),
state_values, state_values, state_values, NumberConstant(0),
UndefinedConstant(), outer_frame_state);
}