Commit 880c4c7b authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

Reland "[heap] Handle bytecode arrays in concurrent marker."

This reverts commit a241576f.

Bytecode array visitor has a side-effect of incrementing the age counter.

This patch makes the increment atomic and thus safe for the concurrent
marker.

Bug: chromium:694255
Change-Id: Ibe1d75714a5911385b06e52ed50b5f152ec6b73d
Reviewed-on: https://chromium-review.googlesource.com/622432
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47472}
parent 1e44e90e
......@@ -161,14 +161,12 @@ class ConcurrentMarkingVisitor final
// ===========================================================================
int VisitBytecodeArray(Map* map, BytecodeArray* object) {
if (marking_state_.IsGrey(object)) {
int size = BytecodeArray::BodyDescriptorWeak::SizeOf(map, object);
VisitMapPointer(object, object->map_slot());
BytecodeArray::BodyDescriptorWeak::IterateBody(object, size, this);
// Aging of bytecode arrays is done on the main thread.
bailout_.Push(object);
}
return 0;
if (!ShouldVisit(object)) return 0;
int size = BytecodeArray::BodyDescriptorWeak::SizeOf(map, object);
VisitMapPointer(object, object->map_slot());
BytecodeArray::BodyDescriptorWeak::IterateBody(object, size, this);
object->MakeOlder();
return size;
}
int VisitAllocationSite(Map* map, AllocationSite* object) {
......
......@@ -2890,14 +2890,16 @@ void BytecodeArray::set_osr_loop_nesting_level(int depth) {
}
BytecodeArray::Age BytecodeArray::bytecode_age() const {
return static_cast<Age>(READ_INT8_FIELD(this, kBytecodeAgeOffset));
// Bytecode is aged by the concurrent marker.
return static_cast<Age>(RELAXED_READ_INT8_FIELD(this, kBytecodeAgeOffset));
}
void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
DCHECK_GE(age, kFirstBytecodeAge);
DCHECK_LE(age, kLastBytecodeAge);
STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
WRITE_INT8_FIELD(this, kBytecodeAgeOffset, static_cast<int8_t>(age));
// Bytecode is aged by the concurrent marker.
RELAXED_WRITE_INT8_FIELD(this, kBytecodeAgeOffset, static_cast<int8_t>(age));
}
int BytecodeArray::parameter_count() const {
......
......@@ -14909,10 +14909,17 @@ void BytecodeArray::CopyBytecodesTo(BytecodeArray* to) {
}
void BytecodeArray::MakeOlder() {
// BytecodeArray is aged in concurrent marker.
// The word must be completely within the byte code array.
Address age_addr = address() + kBytecodeAgeOffset;
DCHECK_LE((reinterpret_cast<uintptr_t>(age_addr) & ~kPointerAlignmentMask) +
kPointerSize,
reinterpret_cast<uintptr_t>(address() + Size()));
Age age = bytecode_age();
if (age < kLastBytecodeAge) {
set_bytecode_age(static_cast<Age>(age + 1));
base::AsAtomic8::Release_CompareAndSwap(age_addr, age, age + 1);
}
DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
DCHECK_LE(bytecode_age(), kLastBytecodeAge);
}
......
......@@ -209,9 +209,17 @@
#define WRITE_UINT8_FIELD(p, offset, value) \
(*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
#define RELAXED_WRITE_INT8_FIELD(p, offset, value) \
base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
static_cast<base::Atomic8>(value));
#define READ_INT8_FIELD(p, offset) \
(*reinterpret_cast<const int8_t*>(FIELD_ADDR_CONST(p, offset)))
#define RELAXED_READ_INT8_FIELD(p, offset) \
static_cast<int8_t>(base::Relaxed_Load( \
reinterpret_cast<const base::Atomic8*>(FIELD_ADDR_CONST(p, offset))))
#define WRITE_INT8_FIELD(p, offset, value) \
(*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
......
......@@ -803,6 +803,27 @@ TEST(BytecodeArray) {
CHECK_NE(array->constant_pool(), old_constant_pool_address);
}
TEST(BytecodeArrayAging) {
static const uint8_t kRawBytes[] = {0xc3, 0x7e, 0xa5, 0x5a};
static const int kRawBytesSize = sizeof(kRawBytes);
static const int kFrameSize = 32;
static const int kParameterCount = 2;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<BytecodeArray> array =
factory->NewBytecodeArray(kRawBytesSize, kRawBytes, kFrameSize,
kParameterCount, factory->empty_fixed_array());
CHECK_EQ(BytecodeArray::kFirstBytecodeAge, array->bytecode_age());
array->MakeOlder();
CHECK_EQ(BytecodeArray::kQuadragenarianBytecodeAge, array->bytecode_age());
array->set_bytecode_age(BytecodeArray::kLastBytecodeAge);
array->MakeOlder();
CHECK_EQ(BytecodeArray::kLastBytecodeAge, array->bytecode_age());
}
static const char* not_so_random_string_table[] = {
"abstract",
......
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