[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
|
||||
// allocation is on.
|
||||
incremental_marking()->IterateBlackObject(new_code);
|
||||
// Record all references to embedded objects in the new code object.
|
||||
RecordWritesIntoCode(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);
|
||||
}
|
||||
|
||||
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() {
|
||||
switch (counter_++) {
|
||||
case NEW_SPACE:
|
||||
@ -5805,7 +5814,6 @@ Space* AllSpaces::next() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PagedSpace* PagedSpaces::next() {
|
||||
switch (counter_++) {
|
||||
case OLD_SPACE:
|
||||
|
@ -1129,6 +1129,7 @@ class Heap {
|
||||
inline void RecordWrite(Object* object, int offset, Object* o);
|
||||
inline void RecordWriteIntoCode(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,
|
||||
int length);
|
||||
|
||||
|
@ -55,9 +55,9 @@ SlotCallbackResult Scavenger::CheckAndScavengeObject(Heap* heap,
|
||||
if (heap->InToSpace(object)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \
|
||||
V(CompactionSpaceDivideMultiplePages) \
|
||||
V(CompactionSpaceDivideSinglePage) \
|
||||
V(TestNewSpaceRefsInCopiedCode) \
|
||||
V(GCFlags) \
|
||||
V(MarkCompactCollector) \
|
||||
V(NoPromotion) \
|
||||
|
@ -99,6 +99,48 @@ static void CheckNumber(Isolate* isolate, double value, const char* 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) {
|
||||
// Test FindCodeObject
|
||||
|
Loading…
Reference in New Issue
Block a user