Commit 54188964 authored by jarin's avatar jarin Committed by Commit bot

Make the frame inspector use TranslatedState rather than the full deoptimizer.

This is mostly preparation for allowing the function closure to be materialized.

As a drive-by fix, I have added ignition source position support to the frame inspector (this fixed some ignition test failures).

Review URL: https://codereview.chromium.org/1698743002

Cr-Commit-Position: refs/heads/master@{#33975}
parent 359ba8e0
......@@ -85,27 +85,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers fp and sp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler());
......
......@@ -65,28 +65,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers fp and sp are set to the correct values though.
for (int i = 0; i < Register::NumRegisters(); i++) {
input_->SetRegister(i, 0);
}
// TODO(all): Do we also need to set a value to csp?
input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint64_at(tos + i));
}
}
bool Deoptimizer::HasAlignmentPadding(SharedFunctionInfo* shared) {
// There is no dynamic alignment padding on ARM64 in the input frame.
return false;
......
......@@ -134,70 +134,26 @@ DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
Isolate* isolate) {
CHECK(frame->is_optimized());
// Get the function and code from the frame.
JSFunction* function = frame->function();
Code* code = frame->LookupCode();
// Locate the deoptimization point in the code. As we are at a call the
// return address must be at a place in the code with deoptimization support.
SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
int deoptimization_index = safepoint_entry.deoptimization_index();
CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
// Always use the actual stack slots when calculating the fp to sp
// delta adding two for the function and context.
unsigned stack_slots = code->stack_slots();
unsigned arguments_stack_height =
Deoptimizer::ComputeOutgoingArgumentSize(code, deoptimization_index);
unsigned fp_to_sp_delta = (stack_slots * kPointerSize) +
StandardFrameConstants::kFixedFrameSizeFromFp +
arguments_stack_height;
Deoptimizer* deoptimizer = new Deoptimizer(isolate,
function,
Deoptimizer::DEBUGGER,
deoptimization_index,
frame->pc(),
fp_to_sp_delta,
code);
Address tos = frame->fp() - fp_to_sp_delta;
deoptimizer->FillInputFrame(tos, frame);
// Calculate the output frames.
Deoptimizer::ComputeOutputFrames(deoptimizer);
// Create the GC safe output frame information and register it for GC
// handling.
CHECK_LT(jsframe_index, deoptimizer->jsframe_count());
// Convert JS frame index into frame index.
int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
bool has_arguments_adaptor =
frame_index > 0 &&
deoptimizer->output_[frame_index - 1]->GetFrameType() ==
StackFrame::ARGUMENTS_ADAPTOR;
int construct_offset = has_arguments_adaptor ? 2 : 1;
bool has_construct_stub =
frame_index >= construct_offset &&
deoptimizer->output_[frame_index - construct_offset]->GetFrameType() ==
StackFrame::CONSTRUCT;
DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer,
frame_index,
has_arguments_adaptor,
has_construct_stub);
// Done with the GC-unsafe frame descriptions. This re-enables allocation.
deoptimizer->DeleteFrameDescriptions();
// Allocate a heap number for the doubles belonging to this frame.
deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
frame_index, info->parameters_count(), info->expression_count(), info);
TranslatedState translated_values(frame);
translated_values.Prepare(false, frame->fp());
TranslatedState::iterator frame_it = translated_values.end();
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 (counter == 0) {
frame_it = it;
break;
}
counter--;
}
}
CHECK(frame_it != translated_values.end());
// Finished using the deoptimizer instance.
delete deoptimizer;
DeoptimizedFrameInfo* info =
new DeoptimizedFrameInfo(&translated_values, frame_it, isolate);
return info;
}
......@@ -563,7 +519,11 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_));
}
unsigned size = ComputeInputFrameSize();
input_ = new(size) FrameDescription(size, function);
int parameter_count =
function == nullptr
? 0
: (function->shared()->internal_formal_parameter_count() + 1);
input_ = new (size) FrameDescription(size, parameter_count);
input_->SetFrameType(frame_type);
}
......@@ -876,7 +836,7 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
height = catch_handler_data_;
// We also make space for the exception itself.
height_in_bytes = (height + 1) * kPointerSize;
DCHECK(is_topmost);
CHECK(is_topmost);
}
JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
......@@ -899,8 +859,9 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, function);
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_);
......@@ -931,7 +892,6 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
output_frame->SetTop(top_address);
// Compute the incoming parameter translation.
int parameter_count = shared->internal_formal_parameter_count() + 1;
unsigned output_offset = output_frame_size;
unsigned input_offset = input_frame_size;
for (int i = 0; i < parameter_count; ++i) {
......@@ -1147,8 +1107,9 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
FrameDescription* output_frame =
new (output_frame_size) FrameDescription(output_frame_size, function);
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::INTERPRETED);
bool is_bottommost = (0 == frame_index);
......@@ -1175,7 +1136,6 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
output_frame->SetTop(top_address);
// Compute the incoming parameter translation.
int parameter_count = shared->internal_formal_parameter_count() + 1;
unsigned output_offset = output_frame_size;
unsigned input_offset = input_frame_size;
for (int i = 0; i < parameter_count; ++i) {
......@@ -1383,8 +1343,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) {
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, function);
int parameter_count = height;
FrameDescription* output_frame = new (output_frame_size)
FrameDescription(output_frame_size, parameter_count);
output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
// Arguments adaptor can not be topmost or bottommost.
......@@ -1399,7 +1360,6 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) {
output_frame->SetTop(top_address);
// Compute the incoming parameter translation.
int parameter_count = height;
unsigned output_offset = output_frame_size;
for (int i = 0; i < parameter_count; ++i) {
output_offset -= kPointerSize;
......@@ -1479,7 +1439,7 @@ void Deoptimizer::DoComputeConstructStubFrame(int frame_index) {
Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize;
JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
// Skip function.
value_iterator++;
input_index++;
if (trace_scope_ != NULL) {
......@@ -1492,7 +1452,7 @@ void Deoptimizer::DoComputeConstructStubFrame(int frame_index) {
// Allocate and store the output frame description.
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, function);
new (output_frame_size) FrameDescription(output_frame_size);
output_frame->SetFrameType(StackFrame::CONSTRUCT);
// Construct stub can not be topmost or bottommost.
......@@ -1605,7 +1565,7 @@ void Deoptimizer::DoComputeAccessorStubFrame(int frame_index,
TranslatedFrame::iterator value_iterator = translated_frame->begin();
int input_index = 0;
JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue());
// Skip accessor.
value_iterator++;
input_index++;
// The receiver (and the implicit return value, if any) are expected in
......@@ -1632,7 +1592,7 @@ void Deoptimizer::DoComputeAccessorStubFrame(int frame_index,
// Allocate and store the output frame description.
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, accessor);
new (output_frame_size) FrameDescription(output_frame_size);
output_frame->SetFrameType(StackFrame::INTERNAL);
// A frame for an accessor stub can not be the topmost or bottommost one.
......@@ -1791,7 +1751,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
// The stub failure trampoline is a single frame.
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, NULL);
new (output_frame_size) FrameDescription(output_frame_size);
output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
CHECK_EQ(frame_index, 0);
output_[frame_index] = output_frame;
......@@ -1992,55 +1952,6 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
}
void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
int frame_index, int parameter_count, int expression_count,
DeoptimizedFrameInfo* info) {
CHECK_EQ(DEBUGGER, bailout_type_);
translated_state_.Prepare(false, nullptr);
TranslatedFrame* frame = &(translated_state_.frames()[frame_index]);
CHECK(frame->kind() == TranslatedFrame::kFunction);
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());
TranslatedFrame* argument_frame = frame;
if (frame_index > 0) {
TranslatedFrame* previous_frame =
&(translated_state_.frames()[frame_index - 1]);
if (previous_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
argument_frame = previous_frame;
CHECK_EQ(parameter_count, argument_frame->height() - 1);
} else {
CHECK_EQ(frame_arg_count, parameter_count);
}
} else {
CHECK_EQ(frame_arg_count, parameter_count);
}
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()) {
info->SetParameter(i, arg_iter->GetValue());
}
}
TranslatedFrame::iterator iter = frame->begin();
// 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++) {
if (!iter->IsMaterializedObject()) {
info->SetExpression(i, iter->GetValue());
}
}
}
void Deoptimizer::WriteTranslatedValueToOutput(
TranslatedFrame::iterator* iterator, int* input_index, int frame_index,
unsigned output_offset, const char* debug_hint_string,
......@@ -2193,11 +2104,9 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
data->deopt_entry_code_entries_[type] = entry_count;
}
FrameDescription::FrameDescription(uint32_t frame_size,
JSFunction* function)
FrameDescription::FrameDescription(uint32_t frame_size, int parameter_count)
: frame_size_(frame_size),
function_(function),
parameter_count_(parameter_count),
top_(kZapUint32),
pc_(kZapUint32),
fp_(kZapUint32),
......@@ -2221,10 +2130,10 @@ FrameDescription::FrameDescription(uint32_t frame_size,
int FrameDescription::ComputeFixedSize() {
if (type_ == StackFrame::INTERPRETED) {
return InterpreterFrameConstants::kFixedFrameSize +
(ComputeParametersCount() + 1) * kPointerSize;
parameter_count() * kPointerSize;
} else {
return StandardFrameConstants::kFixedFrameSize +
(ComputeParametersCount() + 1) * kPointerSize;
parameter_count() * kPointerSize;
}
}
......@@ -2237,54 +2146,13 @@ unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
return base - ((slot_index + 1) * kPointerSize);
} else {
// Incoming parameter.
int arg_size = (ComputeParametersCount() + 1) * kPointerSize;
int arg_size = parameter_count() * kPointerSize;
unsigned base = GetFrameSize() - arg_size;
return base - ((slot_index + 1) * kPointerSize);
}
}
int FrameDescription::ComputeParametersCount() {
switch (type_) {
case StackFrame::JAVA_SCRIPT:
return function_->shared()->internal_formal_parameter_count();
case StackFrame::ARGUMENTS_ADAPTOR: {
// Last slot contains number of incomming arguments as a smi.
// Can't use GetExpression(0) because it would cause infinite recursion.
return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
}
case StackFrame::STUB:
return -1; // Minus receiver.
default:
FATAL("Unexpected stack frame type");
return 0;
}
}
Object* FrameDescription::GetParameter(int index) {
CHECK_GE(index, 0);
CHECK_LT(index, ComputeParametersCount());
// The slot indexes for incoming arguments are negative.
unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
}
unsigned FrameDescription::GetExpressionCount() {
CHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
unsigned size = GetFrameSize() - ComputeFixedSize();
return size / kPointerSize;
}
Object* FrameDescription::GetExpression(int index) {
DCHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
unsigned offset = GetOffsetFromSlotIndex(index);
return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
}
void TranslationBuffer::Add(int32_t value, Zone* zone) {
// This wouldn't handle kMinInt correctly if it ever encountered it.
DCHECK(value != kMinInt);
......@@ -2606,50 +2474,109 @@ Handle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
return new_array;
}
namespace {
DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
int frame_index,
bool has_arguments_adaptor,
bool has_construct_stub) {
FrameDescription* output_frame = deoptimizer->output_[frame_index];
function_ =
Handle<JSFunction>(output_frame->GetFunction(), deoptimizer->isolate());
context_ =
Handle<Object>(reinterpret_cast<Object*>(output_frame->GetContext()),
deoptimizer->isolate());
has_construct_stub_ = has_construct_stub;
expression_stack_.resize(
static_cast<size_t>(output_frame->GetExpressionCount()));
// Get the source position using the unoptimized code.
Address pc = reinterpret_cast<Address>(output_frame->GetPc());
Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
int offset = static_cast<int>(pc - code->instruction_start());
source_position_ = code->SourcePosition(offset);
for (int i = 0; i < static_cast<int>(expression_count()); i++) {
Object* value = output_frame->GetExpression(i);
// Replace materialization markers with the undefined value.
if (value == deoptimizer->isolate()->heap()->arguments_marker()) {
value = deoptimizer->isolate()->heap()->undefined_value();
Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it,
Isolate* isolate) {
if (it->GetRawValue() == isolate->heap()->arguments_marker()) {
if (!it->IsMaterializableByDebugger()) {
return isolate->factory()->undefined_value();
}
SetExpression(i, Handle<Object>(value, deoptimizer->isolate()));
}
return it->GetValue();
}
if (has_arguments_adaptor) {
output_frame = deoptimizer->output_[frame_index - 1];
CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR);
int ComputeSourcePosition(Handle<SharedFunctionInfo> shared,
BailoutId node_id) {
if (shared->HasBytecodeArray()) {
BytecodeArray* bytecodes = shared->bytecode_array();
return bytecodes->SourcePosition(node_id.ToInt());
} else {
Code* non_optimized_code = shared->code();
FixedArray* raw_data = non_optimized_code->deoptimization_data();
DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, *shared);
unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
return non_optimized_code->SourcePosition(pc_offset);
}
}
parameters_.resize(
static_cast<size_t>(output_frame->ComputeParametersCount()));
for (int i = 0; i < output_frame->ComputeParametersCount(); i++) {
Object* value = output_frame->GetParameter(i);
// Replace materialization markers with the undefined value.
if (value == deoptimizer->isolate()->heap()->arguments_marker()) {
value = deoptimizer->isolate()->heap()->undefined_value();
}
SetParameter(i, Handle<Object>(value, deoptimizer->isolate()));
} // namespace
DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
TranslatedState::iterator frame_it,
Isolate* isolate) {
// If the previous frame is an adaptor frame, we will take the parameters
// from there.
TranslatedState::iterator parameter_frame = frame_it;
if (parameter_frame != state->begin()) {
parameter_frame--;
}
int parameter_count;
if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) {
parameter_count = parameter_frame->height() - 1; // Ignore the receiver.
} else {
parameter_frame = frame_it;
parameter_count =
frame_it->shared_info()->internal_formal_parameter_count();
}
TranslatedFrame::iterator parameter_it = parameter_frame->begin();
parameter_it++; // Skip the function.
parameter_it++; // Skip the receiver.
// Figure out whether there is a construct stub frame on top of
// the parameter frame.
has_construct_stub_ =
parameter_frame != state->begin() &&
(parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub;
source_position_ =
ComputeSourcePosition(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.
// In case the debugger mutates this value, we should deoptimize
// the function and remember the value in the materialized value store.
function_ = Handle<JSFunction>::cast(value_it->GetValue());
parameters_.resize(static_cast<size_t>(parameter_count));
for (int i = 0; i < parameter_count; i++) {
Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate);
SetParameter(i, parameter);
parameter_it++;
}
// Skip the function, the receiver and the arguments.
int skip_count =
frame_it->shared_info()->internal_formal_parameter_count() + 2;
TranslatedFrame::iterator stack_it = frame_it->begin();
for (int i = 0; i < skip_count; i++) {
stack_it++;
}
// Get the context.
context_ = GetValueForDebugger(stack_it, isolate);
stack_it++;
// Get the expression stack.
int stack_height = frame_it->height();
if (frame_it->kind() == TranslatedFrame::kFunction) {
// For full-code frames, we should not count the context.
// TODO(jarin): Clean up the indexing in translated frames.
stack_height--;
}
expression_stack_.resize(static_cast<size_t>(stack_height));
for (int i = 0; i < stack_height; i++) {
Handle<Object> expression = GetValueForDebugger(stack_it, isolate);
SetExpression(i, expression);
stack_it++;
}
// For interpreter frame, skip the accumulator.
if (parameter_frame->kind() == TranslatedFrame::kInterpretedFunction) {
stack_it++;
}
CHECK(stack_it == frame_it->end());
}
......@@ -2929,6 +2856,10 @@ bool TranslatedValue::IsMaterializedObject() const {
}
}
bool TranslatedValue::IsMaterializableByDebugger() const {
// At the moment, we only allow materialization of doubles.
return (kind() == kDouble);
}
int TranslatedValue::GetChildrenCount() const {
if (kind() == kCapturedObject || kind() == kArgumentsObject) {
......@@ -3477,7 +3408,7 @@ void TranslatedState::Prepare(bool has_adapted_arguments,
Handle<Object> TranslatedState::MaterializeAt(int frame_index,
int* value_index) {
TranslatedFrame* frame = &(frames_[frame_index]);
DCHECK(static_cast<size_t>(*value_index) < frame->values_.size());
CHECK(static_cast<size_t>(*value_index) < frame->values_.size());
TranslatedValue* slot = &(frame->values_[*value_index]);
(*value_index)++;
......@@ -3633,16 +3564,16 @@ Handle<Object> TranslatedState::MaterializeAt(int frame_index,
TranslatedState::ObjectPosition pos = object_positions_[object_index];
// Make sure the duplicate is refering to a previous object.
DCHECK(pos.frame_index_ < frame_index ||
(pos.frame_index_ == frame_index &&
pos.value_index_ < *value_index - 1));
CHECK(pos.frame_index_ < frame_index ||
(pos.frame_index_ == frame_index &&
pos.value_index_ < *value_index - 1));
Handle<Object> object =
frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
// The object should have a (non-sentinel) value.
DCHECK(!object.is_null() &&
!object.is_identical_to(isolate_->factory()->arguments_marker()));
CHECK(!object.is_null() &&
!object.is_identical_to(isolate_->factory()->arguments_marker()));
slot->value_ = object;
return object;
......@@ -3746,7 +3677,7 @@ void TranslatedState::StoreMaterializedValuesAndDeopt() {
new_store = true;
}
DCHECK_EQ(length, previously_materialized_objects->length());
CHECK_EQ(length, previously_materialized_objects->length());
bool value_changed = false;
for (int i = 0; i < length; i++) {
......@@ -3754,7 +3685,7 @@ void TranslatedState::StoreMaterializedValuesAndDeopt() {
TranslatedValue* value_info =
&(frames_[pos.frame_index_].values_[pos.value_index_]);
DCHECK(value_info->IsMaterializedObject());
CHECK(value_info->IsMaterializedObject());
Handle<Object> value(value_info->GetRawValue(), isolate_);
......@@ -3763,14 +3694,14 @@ void TranslatedState::StoreMaterializedValuesAndDeopt() {
previously_materialized_objects->set(i, *value);
value_changed = true;
} else {
DCHECK(previously_materialized_objects->get(i) == *value);
CHECK(previously_materialized_objects->get(i) == *value);
}
}
}
if (new_store && value_changed) {
materialized_store->Set(stack_frame_pointer_,
previously_materialized_objects);
DCHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind());
CHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind());
Object* const function = frames_[0].front().GetRawValue();
Deoptimizer::DeoptimizeFunction(JSFunction::cast(function));
}
......@@ -3789,7 +3720,7 @@ void TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
Handle<Object> marker = isolate_->factory()->arguments_marker();
int length = static_cast<int>(object_positions_.size());
DCHECK_EQ(length, previously_materialized_objects->length());
CHECK_EQ(length, previously_materialized_objects->length());
for (int i = 0; i < length; i++) {
// For a previously materialized objects, inject their value into the
......@@ -3798,7 +3729,7 @@ void TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
TranslatedState::ObjectPosition pos = object_positions_[i];
TranslatedValue* value_info =
&(frames_[pos.frame_index_].values_[pos.value_index_]);
DCHECK(value_info->IsMaterializedObject());
CHECK(value_info->IsMaterializedObject());
value_info->value_ =
Handle<Object>(previously_materialized_objects->get(i), isolate_);
......
......@@ -27,6 +27,7 @@ class TranslatedValue {
Handle<Object> GetValue();
bool IsMaterializedObject() const;
bool IsMaterializableByDebugger() const;
private:
friend class TranslatedState;
......@@ -508,10 +509,6 @@ class Deoptimizer : public Malloced {
void MaterializeHeapObjects(JavaScriptFrameIterator* it);
void MaterializeHeapNumbersForDebuggerInspectableFrame(
int frame_index, int parameter_count, int expression_count,
DeoptimizedFrameInfo* info);
static void ComputeOutputFrames(Deoptimizer* deoptimizer);
......@@ -645,11 +642,6 @@ class Deoptimizer : public Malloced {
// searching all code objects).
Code* FindDeoptimizingCode(Address addr);
// Fill the input from from a JavaScript frame. This is used when
// the debugger needs to inspect an optimized frame. For normal
// deoptimizations the input frame is filled in generated code.
void FillInputFrame(Address tos, JavaScriptFrame* frame);
// Fill the given output frame's registers to contain the failure handler
// address and the number of parameters for a stub failure trampoline.
void SetPlatformCompiledStubRegisters(FrameDescription* output_frame,
......@@ -744,8 +736,7 @@ class RegisterValues {
class FrameDescription {
public:
FrameDescription(uint32_t frame_size,
JSFunction* function);
explicit FrameDescription(uint32_t frame_size, int parameter_count = 0);
void* operator new(size_t size, uint32_t frame_size) {
// Subtracts kPointerSize, as the member frame_content_ already supplies
......@@ -766,8 +757,6 @@ class FrameDescription {
return static_cast<uint32_t>(frame_size_);
}
JSFunction* GetFunction() const { return function_; }
unsigned GetOffsetFromSlotIndex(int slot_index);
intptr_t GetFrameSlot(unsigned offset) {
......@@ -775,8 +764,7 @@ class FrameDescription {
}
Address GetFramePointerAddress() {
int fp_offset = GetFrameSize() -
(ComputeParametersCount() + 1) * kPointerSize -
int fp_offset = GetFrameSize() - parameter_count() * kPointerSize -
StandardFrameConstants::kCallerSPOffset;
return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
}
......@@ -834,17 +822,8 @@ class FrameDescription {
StackFrame::Type GetFrameType() const { return type_; }
void SetFrameType(StackFrame::Type type) { type_ = type; }
// Get the incoming arguments count.
int ComputeParametersCount();
// Get a parameter value for an unoptimized frame.
Object* GetParameter(int index);
// Get the expression stack height for a unoptimized frame.
unsigned GetExpressionCount();
// Get the expression stack value for an unoptimized frame.
Object* GetExpression(int index);
// Argument count, including receiver.
int parameter_count() { return parameter_count_; }
static int registers_offset() {
return OFFSET_OF(FrameDescription, register_values_.registers_);
......@@ -877,7 +856,7 @@ class FrameDescription {
// keep the variable-size array frame_content_ of type intptr_t at
// the end of the structure aligned.
uintptr_t frame_size_; // Number of bytes.
JSFunction* function_;
int parameter_count_;
RegisterValues register_values_;
intptr_t top_;
intptr_t pc_;
......@@ -1072,10 +1051,9 @@ class MaterializedObjectStore {
// formal parameter count.
class DeoptimizedFrameInfo : public Malloced {
public:
DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
int frame_index,
bool has_arguments_adaptor,
bool has_construct_stub);
DeoptimizedFrameInfo(TranslatedState* state,
TranslatedState::iterator frame_it, Isolate* isolate);
// Return the number of incoming arguments.
int parameters_count() { return static_cast<int>(parameters_.size()); }
......
......@@ -169,27 +169,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers ebp and esp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
intptr_t handler =
......
......@@ -80,27 +80,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers fp and sp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler());
......
......@@ -80,27 +80,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers fp and sp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint64_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler());
......
......@@ -88,31 +88,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers fp and sp are set to the correct values though.
// We ensure the values are Smis to avoid confusing the garbage
// collector in the event that any values are retreived and stored
// elsewhere.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, reinterpret_cast<intptr_t>(Smi::FromInt(i)));
}
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(
i, reinterpret_cast<intptr_t>(Memory::Address_at(tos + i)));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler());
......
......@@ -88,26 +88,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers rbp and rsp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(rsp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(rbp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uintptr_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
intptr_t handler =
......
......@@ -169,27 +169,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
}
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
// Set the register values. The values are not important as there are no
// callee saved registers in JavaScript frames, so all registers are
// spilled. Registers ebp and esp are set to the correct values though.
for (int i = 0; i < Register::kNumRegisters; i++) {
input_->SetRegister(i, i * 4);
}
input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < X87Register::kMaxNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
// Fill the frame content from the actual data on the frame.
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
}
}
void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
intptr_t handler =
......
......@@ -764,12 +764,6 @@
'regress/debug*': [SKIP],
'regress/regress-debug*': [SKIP],
# TODO(yangguo,4690): Failing in debugger DebuggerInspectableFrame.
'for-in-opt': [FAIL],
'regress/regress-4309-2': [FAIL],
'regress/regress-4309-3': [FAIL],
'regress/regress-4309-1': [FAIL],
# TODO(yangguo,4690): debug-scopes.cc failure in ScopeIterator::Type
# DCHECK(context_->IsFunctionContext() || !scope_info->HasContext());
'regress/regress-crbug-582051': [SKIP],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment