Commit bfc5127a authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[compiler] Add extra synchronization to source position table's get/set

Original CL by neis@: http://crrev.com/c/v8/v8/+/2362693/1

Bug: v8:7790, v8:10853
Fixed: v8:10853
Change-Id: If0bd45e9dfb00f8ef1a358953dab1f5e1c9ae29e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2387960Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69742}
parent e43ec59b
...@@ -1655,7 +1655,7 @@ bool Compiler::CollectSourcePositions(Isolate* isolate, ...@@ -1655,7 +1655,7 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
shared_info->GetDebugInfo().HasInstrumentedBytecodeArray()) { shared_info->GetDebugInfo().HasInstrumentedBytecodeArray()) {
ByteArray source_position_table = ByteArray source_position_table =
job->compilation_info()->bytecode_array()->SourcePositionTable(); job->compilation_info()->bytecode_array()->SourcePositionTable();
shared_info->GetDebugBytecodeArray().set_source_position_table( shared_info->GetDebugBytecodeArray().set_synchronized_source_position_table(
source_position_table); source_position_table);
} }
......
...@@ -977,7 +977,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( ...@@ -977,7 +977,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
bytecode_array().parameter_count(), bytecode_array().register_count(), bytecode_array().parameter_count(), bytecode_array().register_count(),
shared_info.object())), shared_info.object())),
source_position_iterator_(std::make_unique<SourcePositionTableIterator>( source_position_iterator_(std::make_unique<SourcePositionTableIterator>(
bytecode_array().source_positions())), bytecode_array().SourcePositionTable())),
bytecode_iterator_( bytecode_iterator_(
std::make_unique<OffHeapBytecodeArray>(bytecode_array())), std::make_unique<OffHeapBytecodeArray>(bytecode_array())),
bytecode_analysis_(broker_->GetBytecodeAnalysis( bytecode_analysis_(broker_->GetBytecodeAnalysis(
......
...@@ -735,8 +735,7 @@ class BytecodeArrayRef : public FixedArrayBaseRef { ...@@ -735,8 +735,7 @@ class BytecodeArrayRef : public FixedArrayBaseRef {
uint8_t get(int index) const; uint8_t get(int index) const;
Address GetFirstBytecodeAddress() const; Address GetFirstBytecodeAddress() const;
// Source position table. Handle<ByteArray> SourcePositionTable() const;
Handle<ByteArray> source_positions() const;
// Constant pool access. // Constant pool access.
Handle<Object> GetConstantAtIndex(int index) const; Handle<Object> GetConstantAtIndex(int index) const;
......
...@@ -3299,9 +3299,8 @@ void BytecodeArrayRef::SerializeForCompilation() { ...@@ -3299,9 +3299,8 @@ void BytecodeArrayRef::SerializeForCompilation() {
data()->AsBytecodeArray()->SerializeForCompilation(broker()); data()->AsBytecodeArray()->SerializeForCompilation(broker());
} }
Handle<ByteArray> BytecodeArrayRef::source_positions() const { Handle<ByteArray> BytecodeArrayRef::SourcePositionTable() const {
return broker()->CanonicalPersistentHandle( return broker()->CanonicalPersistentHandle(object()->SourcePositionTable());
object()->SourcePositionTableIfCollected());
} }
Address BytecodeArrayRef::handler_table_address() const { Address BytecodeArrayRef::handler_table_address() const {
......
...@@ -1025,7 +1025,7 @@ void TranslateSourcePositionTable(Isolate* isolate, Handle<BytecodeArray> code, ...@@ -1025,7 +1025,7 @@ void TranslateSourcePositionTable(Isolate* isolate, Handle<BytecodeArray> code,
Handle<ByteArray> new_source_position_table( Handle<ByteArray> new_source_position_table(
builder.ToSourcePositionTable(isolate)); builder.ToSourcePositionTable(isolate));
code->set_source_position_table(*new_source_position_table); code->set_synchronized_source_position_table(*new_source_position_table);
LOG_CODE_EVENT(isolate, LOG_CODE_EVENT(isolate,
CodeLinePosInfoRecordEvent(code->GetFirstBytecodeAddress(), CodeLinePosInfoRecordEvent(code->GetFirstBytecodeAddress(),
*new_source_position_table)); *new_source_position_table));
......
...@@ -291,9 +291,9 @@ void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) { ...@@ -291,9 +291,9 @@ void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
CHECK(IsBytecodeArray()); CHECK(IsBytecodeArray());
CHECK(constant_pool().IsFixedArray()); CHECK(constant_pool().IsFixedArray());
VerifyHeapPointer(isolate, constant_pool()); VerifyHeapPointer(isolate, constant_pool());
CHECK(source_position_table().IsUndefined() || CHECK(synchronized_source_position_table().IsUndefined() ||
source_position_table().IsException() || synchronized_source_position_table().IsException() ||
source_position_table().IsByteArray()); synchronized_source_position_table().IsByteArray());
CHECK(handler_table().IsByteArray()); CHECK(handler_table().IsByteArray());
} }
......
...@@ -195,7 +195,8 @@ Handle<BytecodeArray> FactoryBase<Impl>::NewBytecodeArray( ...@@ -195,7 +195,8 @@ Handle<BytecodeArray> FactoryBase<Impl>::NewBytecodeArray(
instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge); instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge);
instance->set_constant_pool(*constant_pool); instance->set_constant_pool(*constant_pool);
instance->set_handler_table(read_only_roots().empty_byte_array()); instance->set_handler_table(read_only_roots().empty_byte_array());
instance->set_source_position_table(read_only_roots().undefined_value()); instance->set_synchronized_source_position_table(
read_only_roots().undefined_value());
CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()), CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()),
raw_bytecodes, length); raw_bytecodes, length);
instance->clear_padding(); instance->clear_padding();
......
...@@ -2162,7 +2162,8 @@ Handle<BytecodeArray> Factory::CopyBytecodeArray( ...@@ -2162,7 +2162,8 @@ Handle<BytecodeArray> Factory::CopyBytecodeArray(
bytecode_array->incoming_new_target_or_generator_register()); bytecode_array->incoming_new_target_or_generator_register());
copy->set_constant_pool(bytecode_array->constant_pool()); copy->set_constant_pool(bytecode_array->constant_pool());
copy->set_handler_table(bytecode_array->handler_table()); copy->set_handler_table(bytecode_array->handler_table());
copy->set_source_position_table(bytecode_array->source_position_table()); copy->set_synchronized_source_position_table(
bytecode_array->synchronized_source_position_table());
copy->set_osr_loop_nesting_level(bytecode_array->osr_loop_nesting_level()); copy->set_osr_loop_nesting_level(bytecode_array->osr_loop_nesting_level());
copy->set_bytecode_age(bytecode_array->bytecode_age()); copy->set_bytecode_age(bytecode_array->bytecode_age());
bytecode_array->CopyBytecodesTo(*copy); bytecode_array->CopyBytecodesTo(*copy);
......
...@@ -250,7 +250,7 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::DoFinalizeJobImpl( ...@@ -250,7 +250,7 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::DoFinalizeJobImpl(
SourcePositionTableBuilder::RecordingMode::RECORD_SOURCE_POSITIONS) { SourcePositionTableBuilder::RecordingMode::RECORD_SOURCE_POSITIONS) {
Handle<ByteArray> source_position_table = Handle<ByteArray> source_position_table =
generator()->FinalizeSourcePositionTable(isolate); generator()->FinalizeSourcePositionTable(isolate);
bytecodes->set_source_position_table(*source_position_table); bytecodes->set_synchronized_source_position_table(*source_position_table);
} }
if (ShouldPrintBytecode(shared_info)) { if (ShouldPrintBytecode(shared_info)) {
......
...@@ -208,21 +208,12 @@ void Code::clear_padding() { ...@@ -208,21 +208,12 @@ void Code::clear_padding() {
CodeSize() - (data_end - address())); CodeSize() - (data_end - address()));
} }
ByteArray Code::SourcePositionTableIfCollected() const {
ReadOnlyRoots roots = GetReadOnlyRoots();
Object maybe_table = source_position_table();
if (maybe_table.IsUndefined(roots) || maybe_table.IsException(roots)) {
return roots.empty_byte_array();
}
DCHECK(maybe_table.IsByteArray());
return ByteArray::cast(maybe_table);
}
ByteArray Code::SourcePositionTable() const { ByteArray Code::SourcePositionTable() const {
Object maybe_table = source_position_table(); Object maybe_table = source_position_table();
DCHECK(!maybe_table.IsUndefined() && !maybe_table.IsException()); if (maybe_table.IsByteArray()) return ByteArray::cast(maybe_table);
DCHECK(maybe_table.IsByteArray()); ReadOnlyRoots roots = GetReadOnlyRoots();
return ByteArray::cast(maybe_table); DCHECK(maybe_table.IsUndefined(roots) || maybe_table.IsException(roots));
return roots.empty_byte_array();
} }
Object Code::next_code_link() const { Object Code::next_code_link() const {
...@@ -710,8 +701,8 @@ int32_t BytecodeArray::parameter_count() const { ...@@ -710,8 +701,8 @@ int32_t BytecodeArray::parameter_count() const {
ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset) ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset) ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
ACCESSORS(BytecodeArray, source_position_table, Object, SYNCHRONIZED_ACCESSORS(BytecodeArray, synchronized_source_position_table,
kSourcePositionTableOffset) Object, kSourcePositionTableOffset)
void BytecodeArray::clear_padding() { void BytecodeArray::clear_padding() {
int data_size = kHeaderSize + length(); int data_size = kHeaderSize + length();
...@@ -724,40 +715,37 @@ Address BytecodeArray::GetFirstBytecodeAddress() { ...@@ -724,40 +715,37 @@ Address BytecodeArray::GetFirstBytecodeAddress() {
} }
bool BytecodeArray::HasSourcePositionTable() const { bool BytecodeArray::HasSourcePositionTable() const {
Object maybe_table = source_position_table(); Object maybe_table = synchronized_source_position_table();
return !(maybe_table.IsUndefined() || DidSourcePositionGenerationFail()); return !(maybe_table.IsUndefined() || DidSourcePositionGenerationFail());
} }
bool BytecodeArray::DidSourcePositionGenerationFail() const { bool BytecodeArray::DidSourcePositionGenerationFail() const {
return source_position_table().IsException(); return synchronized_source_position_table().IsException();
} }
void BytecodeArray::SetSourcePositionsFailedToCollect() { void BytecodeArray::SetSourcePositionsFailedToCollect() {
set_source_position_table(GetReadOnlyRoots().exception()); set_synchronized_source_position_table(GetReadOnlyRoots().exception());
} }
ByteArray BytecodeArray::SourcePositionTable() const { ByteArray BytecodeArray::SourcePositionTable() const {
Object maybe_table = source_position_table(); // WARNING: This function may be called from a background thread, hence
// changes to how it accesses the heap can easily lead to bugs.
Object maybe_table = synchronized_source_position_table();
if (maybe_table.IsByteArray()) return ByteArray::cast(maybe_table); if (maybe_table.IsByteArray()) return ByteArray::cast(maybe_table);
ReadOnlyRoots roots = GetReadOnlyRoots(); ReadOnlyRoots roots = GetReadOnlyRoots();
DCHECK(maybe_table.IsException(roots)); DCHECK(maybe_table.IsUndefined(roots) || maybe_table.IsException(roots));
return roots.empty_byte_array(); return roots.empty_byte_array();
} }
ByteArray BytecodeArray::SourcePositionTableIfCollected() const {
if (!HasSourcePositionTable()) return GetReadOnlyRoots().empty_byte_array();
return SourcePositionTable();
}
int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); } int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
int BytecodeArray::SizeIncludingMetadata() { int BytecodeArray::SizeIncludingMetadata() {
int size = BytecodeArraySize(); int size = BytecodeArraySize();
size += constant_pool().Size(); size += constant_pool().Size();
size += handler_table().Size(); size += handler_table().Size();
if (HasSourcePositionTable()) { ByteArray table = SourcePositionTable();
size += SourcePositionTable().Size(); if (table.length() != 0) {
size += table.Size();
} }
return size; return size;
} }
......
...@@ -712,8 +712,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate, ...@@ -712,8 +712,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
{ {
SourcePositionTableIterator it( SourcePositionTableIterator it(
SourcePositionTableIfCollected(), SourcePositionTable(), SourcePositionTableIterator::kJavaScriptOnly);
SourcePositionTableIterator::kJavaScriptOnly);
if (!it.done()) { if (!it.done()) {
os << "Source positions:\n pc offset position\n"; os << "Source positions:\n pc offset position\n";
for (; !it.done(); it.Advance()) { for (; !it.done(); it.Advance()) {
...@@ -726,7 +725,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate, ...@@ -726,7 +725,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
} }
{ {
SourcePositionTableIterator it(SourcePositionTableIfCollected(), SourcePositionTableIterator it(SourcePositionTable(),
SourcePositionTableIterator::kExternalOnly); SourcePositionTableIterator::kExternalOnly);
if (!it.done()) { if (!it.done()) {
os << "External Source positions:\n pc offset fileid line\n"; os << "External Source positions:\n pc offset fileid line\n";
...@@ -808,8 +807,7 @@ void BytecodeArray::Disassemble(std::ostream& os) { ...@@ -808,8 +807,7 @@ void BytecodeArray::Disassemble(std::ostream& os) {
os << "Frame size " << frame_size() << "\n"; os << "Frame size " << frame_size() << "\n";
Address base_address = GetFirstBytecodeAddress(); Address base_address = GetFirstBytecodeAddress();
SourcePositionTableIterator source_positions( SourcePositionTableIterator source_positions(SourcePositionTable());
SourcePositionTableIfCollected());
// Storage for backing the handle passed to the iterator. This handle won't be // Storage for backing the handle passed to the iterator. This handle won't be
// updated by the gc, but that's ok because we've disallowed GCs anyway. // updated by the gc, but that's ok because we've disallowed GCs anyway.
...@@ -868,11 +866,12 @@ void BytecodeArray::Disassemble(std::ostream& os) { ...@@ -868,11 +866,12 @@ void BytecodeArray::Disassemble(std::ostream& os) {
} }
#endif #endif
os << "Source Position Table (size = " ByteArray source_position_table = SourcePositionTable();
<< SourcePositionTableIfCollected().length() << ")\n"; os << "Source Position Table (size = " << source_position_table.length()
<< ")\n";
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
if (SourcePositionTableIfCollected().length() > 0) { if (source_position_table.length() > 0) {
os << Brief(SourcePositionTableIfCollected()) << std::endl; os << Brief(source_position_table) << std::endl;
} }
#endif #endif
} }
......
...@@ -109,8 +109,10 @@ class Code : public HeapObject { ...@@ -109,8 +109,10 @@ class Code : public HeapObject {
// [source_position_table]: ByteArray for the source positions table. // [source_position_table]: ByteArray for the source positions table.
DECL_ACCESSORS(source_position_table, Object) DECL_ACCESSORS(source_position_table, Object)
// If source positions have not been collected or an exception has been thrown
// this will return empty_byte_array.
inline ByteArray SourcePositionTable() const; inline ByteArray SourcePositionTable() const;
inline ByteArray SourcePositionTableIfCollected() const;
// [code_data_container]: A container indirection for all mutable fields. // [code_data_container]: A container indirection for all mutable fields.
DECL_ACCESSORS(code_data_container, CodeDataContainer) DECL_ACCESSORS(code_data_container, CodeDataContainer)
...@@ -773,18 +775,15 @@ class BytecodeArray : public FixedArrayBase { ...@@ -773,18 +775,15 @@ class BytecodeArray : public FixedArrayBase {
// * ByteArray (when source positions have been collected for the bytecode) // * ByteArray (when source positions have been collected for the bytecode)
// * exception (when an error occurred while explicitly collecting source // * exception (when an error occurred while explicitly collecting source
// positions for pre-existing bytecode). // positions for pre-existing bytecode).
DECL_ACCESSORS(source_position_table, Object) DECL_SYNCHRONIZED_ACCESSORS(source_position_table, Object)
// This must only be called if source position collection has already been
// attempted. (If it failed because of an exception then it will return
// empty_byte_array).
inline ByteArray SourcePositionTable() const;
// If source positions have not been collected or an exception has been thrown
// this will return empty_byte_array.
inline ByteArray SourcePositionTableIfCollected() const;
inline bool HasSourcePositionTable() const; inline bool HasSourcePositionTable() const;
inline bool DidSourcePositionGenerationFail() const; inline bool DidSourcePositionGenerationFail() const;
// If source positions have not been collected or an exception has been thrown
// this will return empty_byte_array.
inline ByteArray SourcePositionTable() const;
// Indicates that an attempt was made to collect source positions, but that it // Indicates that an attempt was made to collect source positions, but that it
// failed most likely due to stack exhaustion. When in this state // failed most likely due to stack exhaustion. When in this state
// |SourcePositionTable| will return an empty byte array rather than crashing // |SourcePositionTable| will return an empty byte array rather than crashing
......
...@@ -121,6 +121,12 @@ ...@@ -121,6 +121,12 @@
V8_EXPORT_PRIVATE void set_##name( \ V8_EXPORT_PRIVATE void set_##name( \
type value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); type value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// TODO(solanes, neis): Unify naming for synchronized accessor uses.
#define DECL_SYNCHRONIZED_ACCESSORS(name, type) \
DECL_GETTER(synchronized_##name, type) \
inline void set_synchronized_##name( \
type value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
#define DECL_CAST_NONINLINE(Type) \ #define DECL_CAST_NONINLINE(Type) \
V8_EXPORT_PRIVATE static Type cast(Object object); \ V8_EXPORT_PRIVATE static Type cast(Object object); \
inline static Type unchecked_cast(Object object) { \ inline static Type unchecked_cast(Object object) { \
......
...@@ -142,7 +142,7 @@ TEST_F(BytecodeArrayWriterUnittest, SimpleExample) { ...@@ -142,7 +142,7 @@ TEST_F(BytecodeArrayWriterUnittest, SimpleExample) {
Handle<BytecodeArray> bytecode_array = Handle<BytecodeArray> bytecode_array =
writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array()); writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array());
bytecode_array->set_source_position_table( bytecode_array->set_synchronized_source_position_table(
*writer()->ToSourcePositionTable(isolate())); *writer()->ToSourcePositionTable(isolate()));
CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes)); CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes));
...@@ -229,7 +229,7 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) { ...@@ -229,7 +229,7 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
Handle<BytecodeArray> bytecode_array = Handle<BytecodeArray> bytecode_array =
writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array()); writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array());
bytecode_array->set_source_position_table( bytecode_array->set_synchronized_source_position_table(
*writer()->ToSourcePositionTable(isolate())); *writer()->ToSourcePositionTable(isolate()));
SourcePositionTableIterator source_iterator( SourcePositionTableIterator source_iterator(
bytecode_array->SourcePositionTable()); bytecode_array->SourcePositionTable());
...@@ -278,7 +278,7 @@ TEST_F(BytecodeArrayWriterUnittest, ElideNoneffectfulBytecodes) { ...@@ -278,7 +278,7 @@ TEST_F(BytecodeArrayWriterUnittest, ElideNoneffectfulBytecodes) {
Handle<BytecodeArray> bytecode_array = Handle<BytecodeArray> bytecode_array =
writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array()); writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array());
bytecode_array->set_source_position_table( bytecode_array->set_synchronized_source_position_table(
*writer()->ToSourcePositionTable(isolate())); *writer()->ToSourcePositionTable(isolate()));
SourcePositionTableIterator source_iterator( SourcePositionTableIterator source_iterator(
bytecode_array->SourcePositionTable()); bytecode_array->SourcePositionTable());
...@@ -346,7 +346,7 @@ TEST_F(BytecodeArrayWriterUnittest, DeadcodeElimination) { ...@@ -346,7 +346,7 @@ TEST_F(BytecodeArrayWriterUnittest, DeadcodeElimination) {
Handle<BytecodeArray> bytecode_array = Handle<BytecodeArray> bytecode_array =
writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array()); writer()->ToBytecodeArray(isolate(), 0, 0, factory()->empty_byte_array());
bytecode_array->set_source_position_table( bytecode_array->set_synchronized_source_position_table(
*writer()->ToSourcePositionTable(isolate())); *writer()->ToSourcePositionTable(isolate()));
SourcePositionTableIterator source_iterator( SourcePositionTableIterator source_iterator(
bytecode_array->SourcePositionTable()); bytecode_array->SourcePositionTable());
......
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