[runtime] Allocate DeoptimizationData before Code objects.

This allocates and populates potential deoptimization data arrays before
the underlying {Code} objects is allocated. It aims at making the field
holding said data immutable after allocation. Note that we still mutate
this field during deoptimization.

R=verwaest@chromium.org
BUG=v8:6792

Change-Id: Id0c2cfb65e782d7292d2df6bff41c54b2b8c3351
Reviewed-on: https://chromium-review.googlesource.com/725704
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48738}
This commit is contained in:
Michael Starzinger 2017-10-18 14:50:14 +02:00 committed by Commit Bot
parent 34a575f496
commit 52d54f7c2a
8 changed files with 30 additions and 12 deletions

View File

@ -129,7 +129,8 @@ Handle<Code> PlatformCodeStub::GenerateCode() {
masm.GetCode(isolate(), &desc);
// Copy the generated code into a heap object.
Handle<Code> new_object = factory->NewCode(
desc, Code::STUB, masm.CodeObject(), table, NeedsImmovableCode());
desc, Code::STUB, masm.CodeObject(), table,
DeoptimizationData::Empty(isolate()), NeedsImmovableCode());
return new_object;
}

View File

@ -290,6 +290,9 @@ Handle<Code> CodeGenerator::FinalizeCode() {
}
}
// Allocate deoptimization data.
Handle<DeoptimizationData> deopt_data = GenerateDeoptimizationData();
// Allocate and install the code.
CodeDesc desc;
tasm()->GetCode(isolate(), &desc);
@ -298,7 +301,7 @@ Handle<Code> CodeGenerator::FinalizeCode() {
}
Handle<Code> result = isolate()->factory()->NewCode(
desc, info()->code_kind(), Handle<Object>(), table, false);
desc, info()->code_kind(), Handle<Object>(), table, deopt_data, false);
isolate()->counters()->total_compiled_code_size()->Increment(
result->instruction_size());
result->set_is_turbofanned(true);
@ -309,8 +312,6 @@ Handle<Code> CodeGenerator::FinalizeCode() {
isolate(), Handle<AbstractCode>::cast(result));
result->set_source_position_table(*source_positions);
PopulateDeoptimizationData(result);
return result;
}
@ -606,10 +607,12 @@ Handle<PodArray<InliningPosition>> CreateInliningPositions(
} // namespace
void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
Handle<DeoptimizationData> CodeGenerator::GenerateDeoptimizationData() {
CompilationInfo* info = this->info();
int deopt_count = static_cast<int>(deoptimization_states_.size());
if (deopt_count == 0 && !info->is_osr()) return;
if (deopt_count == 0 && !info->is_osr()) {
return DeoptimizationData::Empty(isolate());
}
Handle<DeoptimizationData> data =
DeoptimizationData::New(isolate(), deopt_count, TENURED);
@ -658,7 +661,7 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset()));
}
code_object->set_deoptimization_data(*data);
return data;
}

View File

@ -252,7 +252,7 @@ class CodeGenerator final : public GapResolver::Assembler {
// ===========================================================================
void RecordCallPosition(Instruction* instr);
void PopulateDeoptimizationData(Handle<Code> code);
Handle<DeoptimizationData> GenerateDeoptimizationData();
int DefineDeoptimizationLiteral(DeoptimizationLiteral literal);
DeoptimizationEntry const& GetDeoptimizationEntry(Instruction* instr,
size_t frame_state_offset);

View File

@ -1786,12 +1786,16 @@ Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
Handle<Code> Factory::NewCode(const CodeDesc& desc, Code::Kind kind,
Handle<Object> self_ref,
MaybeHandle<HandlerTable> maybe_handler_table,
MaybeHandle<DeoptimizationData> maybe_deopt_data,
bool immovable) {
Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
Handle<HandlerTable> handler_table =
maybe_handler_table.is_null() ? HandlerTable::Empty(isolate())
: maybe_handler_table.ToHandleChecked();
Handle<DeoptimizationData> deopt_data =
maybe_deopt_data.is_null() ? DeoptimizationData::Empty(isolate())
: maybe_deopt_data.ToHandleChecked();
bool has_unwinding_info = desc.unwinding_info != nullptr;
DCHECK((has_unwinding_info && desc.unwinding_info_size > 0) ||
@ -1822,7 +1826,7 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc, Code::Kind kind,
code->set_raw_kind_specific_flags1(0);
code->set_raw_kind_specific_flags2(0);
code->set_has_tagged_params(true);
code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER);
code->set_deoptimization_data(*deopt_data);
code->set_raw_type_feedback_info(Smi::kZero);
code->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
code->set_handler_table(*handler_table);

View File

@ -678,6 +678,8 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<Object> self_reference,
MaybeHandle<HandlerTable> maybe_handler_table =
MaybeHandle<HandlerTable>(),
MaybeHandle<DeoptimizationData> deopt_data =
MaybeHandle<DeoptimizationData>(),
bool immovable = false);
// Allocates a new, empty code object for use by builtin deserialization. The

View File

@ -10477,6 +10477,11 @@ Handle<DeoptimizationData> DeoptimizationData::New(Isolate* isolate,
LengthFor(deopt_entry_count), pretenure));
}
Handle<DeoptimizationData> DeoptimizationData::Empty(Isolate* isolate) {
return Handle<DeoptimizationData>::cast(
isolate->factory()->empty_fixed_array());
}
SharedFunctionInfo* DeoptimizationData::GetInlinedFunction(int index) {
if (index == -1) {
return SharedFunctionInfo::cast(SharedFunctionInfo());

View File

@ -904,6 +904,9 @@ class DeoptimizationData : public FixedArray {
static Handle<DeoptimizationData> New(Isolate* isolate, int deopt_entry_count,
PretenureFlag pretenure);
// Return an empty DeoptimizationData.
static Handle<DeoptimizationData> Empty(Isolate* isolate);
DECL_CAST(DeoptimizationData)
#ifdef ENABLE_DISASSEMBLER

View File

@ -5776,9 +5776,9 @@ Handle<Code> GenerateDummyImmovableCode(Isolate* isolate) {
CodeDesc desc;
assm.GetCode(isolate, &desc);
const bool kImmovable = true;
Handle<Code> code =
isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>(),
HandlerTable::Empty(isolate), kImmovable);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::STUB, Handle<Code>(), HandlerTable::Empty(isolate),
DeoptimizationData::Empty(isolate), kImmovable);
CHECK(code->IsCode());
return code;