[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:
parent
34a575f496
commit
52d54f7c2a
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user