[heap] Record references in the new code objects in heap::CopyCode.
R=mlippautz@chromium.org BUG=chromium:633539 TEST=cctest/test-heap/TestNewSpaceRefsInCopiedCode Review-Url: https://codereview.chromium.org/2203783002 Cr-Commit-Position: refs/heads/master@{#38326}
This commit is contained in:
parent
ea6b9609a6
commit
c088aea922
@ -3373,6 +3373,8 @@ AllocationResult Heap::CopyCode(Code* code) {
|
|||||||
// We have to iterate over the object and process its pointers when black
|
// We have to iterate over the object and process its pointers when black
|
||||||
// allocation is on.
|
// allocation is on.
|
||||||
incremental_marking()->IterateBlackObject(new_code);
|
incremental_marking()->IterateBlackObject(new_code);
|
||||||
|
// Record all references to embedded objects in the new code object.
|
||||||
|
RecordWritesIntoCode(new_code);
|
||||||
return new_code;
|
return new_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5788,6 +5790,13 @@ void Heap::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
|
|||||||
source_page, reinterpret_cast<Address>(host), slot_type, addr);
|
source_page, reinterpret_cast<Address>(host), slot_type, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Heap::RecordWritesIntoCode(Code* code) {
|
||||||
|
for (RelocIterator it(code, RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT));
|
||||||
|
!it.done(); it.next()) {
|
||||||
|
RecordWriteIntoCode(code, it.rinfo(), it.rinfo()->target_object());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Space* AllSpaces::next() {
|
Space* AllSpaces::next() {
|
||||||
switch (counter_++) {
|
switch (counter_++) {
|
||||||
case NEW_SPACE:
|
case NEW_SPACE:
|
||||||
@ -5805,7 +5814,6 @@ Space* AllSpaces::next() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PagedSpace* PagedSpaces::next() {
|
PagedSpace* PagedSpaces::next() {
|
||||||
switch (counter_++) {
|
switch (counter_++) {
|
||||||
case OLD_SPACE:
|
case OLD_SPACE:
|
||||||
|
@ -1129,6 +1129,7 @@ class Heap {
|
|||||||
inline void RecordWrite(Object* object, int offset, Object* o);
|
inline void RecordWrite(Object* object, int offset, Object* o);
|
||||||
inline void RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* target);
|
inline void RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* target);
|
||||||
void RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, Object* target);
|
void RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, Object* target);
|
||||||
|
void RecordWritesIntoCode(Code* code);
|
||||||
inline void RecordFixedArrayElements(FixedArray* array, int offset,
|
inline void RecordFixedArrayElements(FixedArray* array, int offset,
|
||||||
int length);
|
int length);
|
||||||
|
|
||||||
|
@ -55,9 +55,9 @@ SlotCallbackResult Scavenger::CheckAndScavengeObject(Heap* heap,
|
|||||||
if (heap->InToSpace(object)) {
|
if (heap->InToSpace(object)) {
|
||||||
return KEEP_SLOT;
|
return KEEP_SLOT;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
DCHECK(!heap->InNewSpace(object));
|
|
||||||
}
|
}
|
||||||
|
// Slots can point to "to" space if the slot has been recorded multiple
|
||||||
|
// times in the remembered set. We remove the redundant slot now.
|
||||||
return REMOVE_SLOT;
|
return REMOVE_SLOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \
|
V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \
|
||||||
V(CompactionSpaceDivideMultiplePages) \
|
V(CompactionSpaceDivideMultiplePages) \
|
||||||
V(CompactionSpaceDivideSinglePage) \
|
V(CompactionSpaceDivideSinglePage) \
|
||||||
|
V(TestNewSpaceRefsInCopiedCode) \
|
||||||
V(GCFlags) \
|
V(GCFlags) \
|
||||||
V(MarkCompactCollector) \
|
V(MarkCompactCollector) \
|
||||||
V(NoPromotion) \
|
V(NoPromotion) \
|
||||||
|
@ -99,6 +99,48 @@ static void CheckNumber(Isolate* isolate, double value, const char* string) {
|
|||||||
CHECK(String::cast(*print_string)->IsUtf8EqualTo(CStrVector(string)));
|
CHECK(String::cast(*print_string)->IsUtf8EqualTo(CStrVector(string)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckEmbeddedObjectsAreEqual(Handle<Code> lhs, Handle<Code> rhs) {
|
||||||
|
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
||||||
|
RelocIterator lhs_it(*lhs, mode_mask);
|
||||||
|
RelocIterator rhs_it(*rhs, mode_mask);
|
||||||
|
while (!lhs_it.done() && !rhs_it.done()) {
|
||||||
|
CHECK(lhs_it.rinfo()->target_object() == rhs_it.rinfo()->target_object());
|
||||||
|
|
||||||
|
lhs_it.next();
|
||||||
|
rhs_it.next();
|
||||||
|
}
|
||||||
|
CHECK(lhs_it.done() == rhs_it.done());
|
||||||
|
}
|
||||||
|
|
||||||
|
HEAP_TEST(TestNewSpaceRefsInCopiedCode) {
|
||||||
|
CcTest::InitializeVM();
|
||||||
|
Isolate* isolate = CcTest::i_isolate();
|
||||||
|
Factory* factory = isolate->factory();
|
||||||
|
Heap* heap = isolate->heap();
|
||||||
|
HandleScope sc(isolate);
|
||||||
|
|
||||||
|
Handle<Object> value = factory->NewNumber(1.000123);
|
||||||
|
CHECK(heap->InNewSpace(*value));
|
||||||
|
|
||||||
|
i::byte buffer[i::Assembler::kMinimalBufferSize];
|
||||||
|
MacroAssembler masm(isolate, buffer, sizeof(buffer),
|
||||||
|
v8::internal::CodeObjectRequired::kYes);
|
||||||
|
// Add a new-space reference to the code.
|
||||||
|
masm.Push(value);
|
||||||
|
|
||||||
|
CodeDesc desc;
|
||||||
|
masm.GetCode(&desc);
|
||||||
|
Handle<Code> code = isolate->factory()->NewCode(
|
||||||
|
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
||||||
|
|
||||||
|
Code* tmp = nullptr;
|
||||||
|
heap->CopyCode(*code).To(&tmp);
|
||||||
|
Handle<Code> copy(tmp);
|
||||||
|
|
||||||
|
CheckEmbeddedObjectsAreEqual(code, copy);
|
||||||
|
heap->CollectAllAvailableGarbage();
|
||||||
|
CheckEmbeddedObjectsAreEqual(code, copy);
|
||||||
|
}
|
||||||
|
|
||||||
static void CheckFindCodeObject(Isolate* isolate) {
|
static void CheckFindCodeObject(Isolate* isolate) {
|
||||||
// Test FindCodeObject
|
// Test FindCodeObject
|
||||||
|
Loading…
Reference in New Issue
Block a user