[runtime] Allocate source position table before Code.

This allocates and populates potential source position table before the
underlying {Code} objects is allocated. It essentially makes the field
holding said table immutable after allocation.

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

Change-Id: If35462688a1b502f28ae84f73b82b5df5005735f
Reviewed-on: https://chromium-review.googlesource.com/727895
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48781}
This commit is contained in:
Michael Starzinger 2017-10-19 16:42:43 +02:00 committed by Commit Bot
parent bd19ea4a06
commit 035b4ccfc9
12 changed files with 43 additions and 37 deletions

View File

@ -129,7 +129,7 @@ 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,
desc, Code::STUB, masm.CodeObject(), table, MaybeHandle<ByteArray>(),
DeoptimizationData::Empty(isolate()), NeedsImmovableCode());
return new_object;
}

View File

@ -290,6 +290,10 @@ Handle<Code> CodeGenerator::FinalizeCode() {
}
}
// Allocate the source position table.
Handle<ByteArray> source_positions =
source_position_table_builder_.ToSourcePositionTable(isolate());
// Allocate deoptimization data.
Handle<DeoptimizationData> deopt_data = GenerateDeoptimizationData();
@ -300,17 +304,18 @@ Handle<Code> CodeGenerator::FinalizeCode() {
unwinding_info_writer_.eh_frame_writer()->GetEhFrame(&desc);
}
Handle<Code> result = isolate()->factory()->NewCode(
desc, info()->code_kind(), Handle<Object>(), table, deopt_data, false);
Handle<Code> result =
isolate()->factory()->NewCode(desc, info()->code_kind(), Handle<Object>(),
table, source_positions, deopt_data, false);
isolate()->counters()->total_compiled_code_size()->Increment(
result->instruction_size());
result->set_is_turbofanned(true);
result->set_stack_slots(frame()->GetTotalFrameSlotCount());
result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
Handle<ByteArray> source_positions =
source_position_table_builder_.ToSourcePositionTable(
isolate(), Handle<AbstractCode>::cast(result));
result->set_source_position_table(*source_positions);
LOG_CODE_EVENT(isolate(),
CodeLinePosInfoRecordEvent(*Handle<AbstractCode>::cast(result),
*source_positions));
return result;
}

View File

@ -962,8 +962,11 @@ void TranslateSourcePositionTable(Handle<BytecodeArray> code,
}
Handle<ByteArray> new_source_position_table(
builder.ToSourcePositionTable(isolate, Handle<AbstractCode>::cast(code)));
builder.ToSourcePositionTable(isolate));
code->set_source_position_table(*new_source_position_table);
LOG_CODE_EVENT(isolate,
CodeLinePosInfoRecordEvent(*Handle<AbstractCode>::cast(code),
*new_source_position_table));
}
} // namespace

View File

@ -1783,16 +1783,20 @@ Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
Code);
}
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<Code> Factory::NewCode(
const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref,
MaybeHandle<HandlerTable> maybe_handler_table,
MaybeHandle<ByteArray> maybe_source_position_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<ByteArray> source_position_table =
maybe_source_position_table.is_null()
? empty_byte_array()
: maybe_source_position_table.ToHandleChecked();
Handle<DeoptimizationData> deopt_data =
maybe_deopt_data.is_null() ? DeoptimizationData::Empty(isolate())
: maybe_deopt_data.ToHandleChecked();
@ -1831,7 +1835,7 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc, Code::Kind kind,
code->set_raw_type_feedback_info(Smi::kZero);
code->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
code->set_handler_table(*handler_table);
code->set_source_position_table(*empty_byte_array(), SKIP_WRITE_BARRIER);
code->set_source_position_table(*source_position_table);
code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
code->set_builtin_index(-1);
code->set_trap_handler_index(Smi::FromInt(-1));

View File

@ -678,7 +678,9 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<Object> self_reference,
MaybeHandle<HandlerTable> maybe_handler_table =
MaybeHandle<HandlerTable>(),
MaybeHandle<DeoptimizationData> deopt_data =
MaybeHandle<ByteArray> maybe_source_position_table =
MaybeHandle<ByteArray>(),
MaybeHandle<DeoptimizationData> maybe_deopt_data =
MaybeHandle<DeoptimizationData>(),
bool immovable = false);

View File

@ -45,14 +45,16 @@ Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
int frame_size = register_count * kPointerSize;
Handle<FixedArray> constant_pool =
constant_array_builder()->ToFixedArray(isolate);
Handle<ByteArray> source_position_table =
source_position_table_builder()->ToSourcePositionTable(isolate);
Handle<BytecodeArray> bytecode_array = isolate->factory()->NewBytecodeArray(
bytecode_size, &bytecodes()->front(), frame_size, parameter_count,
constant_pool);
bytecode_array->set_handler_table(*handler_table);
Handle<ByteArray> source_position_table =
source_position_table_builder()->ToSourcePositionTable(
isolate, Handle<AbstractCode>::cast(bytecode_array));
bytecode_array->set_source_position_table(*source_position_table);
LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(
*Handle<AbstractCode>::cast(bytecode_array),
*source_position_table));
return bytecode_array;
}

View File

@ -13,6 +13,7 @@
namespace v8 {
namespace internal {
class BytecodeArray;
class SourcePositionTableBuilder;
namespace interpreter {

View File

@ -1280,7 +1280,7 @@ void Logger::CodeMoveEvent(AbstractCode* from, Address to) {
void Logger::CodeLinePosInfoRecordEvent(AbstractCode* code,
ByteArray* source_position_table) {
if (jit_logger_) {
if (jit_logger_ && source_position_table->length() > 0) {
void* jit_handler_data = jit_logger_->StartCodePosInfoEvent();
for (SourcePositionTableIterator iter(source_position_table); !iter.done();
iter.Advance()) {

View File

@ -4,7 +4,6 @@
#include "src/source-position-table.h"
#include "src/log.h"
#include "src/objects-inl.h"
#include "src/objects.h"
@ -138,7 +137,7 @@ void SourcePositionTableBuilder::AddEntry(const PositionTableEntry& entry) {
}
Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
Isolate* isolate, Handle<AbstractCode> code) {
Isolate* isolate) {
if (bytes_.empty()) return isolate->factory()->empty_byte_array();
DCHECK(!Omit());
@ -147,8 +146,6 @@ Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable(
MemCopy(table->GetDataStartAddress(), &*bytes_.begin(), bytes_.size());
LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(*code, *table));
#ifdef ENABLE_SLOW_DCHECKS
// Brute force testing: Record all positions and decode
// the entire table to verify they are identical.

View File

@ -14,8 +14,6 @@
namespace v8 {
namespace internal {
class AbstractCode;
class BytecodeArray;
class ByteArray;
template <typename T>
class Handle;
@ -43,8 +41,7 @@ class V8_EXPORT_PRIVATE SourcePositionTableBuilder {
void AddPosition(size_t code_offset, SourcePosition source_position,
bool is_statement);
Handle<ByteArray> ToSourcePositionTable(Isolate* isolate,
Handle<AbstractCode> code);
Handle<ByteArray> ToSourcePositionTable(Isolate* isolate);
private:
void AddEntry(const PositionTableEntry& entry);

View File

@ -5778,7 +5778,7 @@ Handle<Code> GenerateDummyImmovableCode(Isolate* isolate) {
const bool kImmovable = true;
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::STUB, Handle<Code>(), HandlerTable::Empty(isolate),
DeoptimizationData::Empty(isolate), kImmovable);
MaybeHandle<ByteArray>(), DeoptimizationData::Empty(isolate), kImmovable);
CHECK(code->IsCode());
return code;

View File

@ -5,7 +5,6 @@
#include "src/v8.h"
#include "src/objects.h"
#include "src/objects/code.h"
#include "src/source-position-table.h"
#include "test/unittests/test-utils.h"
@ -36,8 +35,7 @@ TEST_F(SourcePositionTableTest, EncodeStatement) {
// To test correctness, we rely on the assertions in ToSourcePositionTable().
// (Also below.)
CHECK(!builder.ToSourcePositionTable(isolate(), Handle<AbstractCode>())
.is_null());
CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}
TEST_F(SourcePositionTableTest, EncodeStatementDuplicates) {
@ -49,8 +47,7 @@ TEST_F(SourcePositionTableTest, EncodeStatementDuplicates) {
// To test correctness, we rely on the assertions in ToSourcePositionTable().
// (Also below.)
CHECK(!builder.ToSourcePositionTable(isolate(), Handle<AbstractCode>())
.is_null());
CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}
TEST_F(SourcePositionTableTest, EncodeExpression) {
@ -58,8 +55,7 @@ TEST_F(SourcePositionTableTest, EncodeExpression) {
for (size_t i = 0; i < arraysize(offsets); i++) {
builder.AddPosition(offsets[i], toPos(offsets[i]), false);
}
CHECK(!builder.ToSourcePositionTable(isolate(), Handle<AbstractCode>())
.is_null());
CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}
TEST_F(SourcePositionTableTest, EncodeAscending) {
@ -88,8 +84,7 @@ TEST_F(SourcePositionTableTest, EncodeAscending) {
}
}
CHECK(!builder.ToSourcePositionTable(isolate(), Handle<AbstractCode>())
.is_null());
CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}
} // namespace interpreter