[serializer] fix deserializing cell targets in code.
R=mtrofin@chromium.org Review-Url: https://codereview.chromium.org/1989203004 Cr-Commit-Position: refs/heads/master@{#36363}
This commit is contained in:
parent
c57cadfa09
commit
806739279a
@ -503,12 +503,11 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
emit_write_barrier = false; \
|
||||
} \
|
||||
if (within == kInnerPointer) { \
|
||||
if (space_number != CODE_SPACE || new_object->IsCode()) { \
|
||||
Code* new_code_object = reinterpret_cast<Code*>(new_object); \
|
||||
if (new_object->IsCode()) { \
|
||||
Code* new_code_object = Code::cast(new_object); \
|
||||
new_object = \
|
||||
reinterpret_cast<Object*>(new_code_object->instruction_start()); \
|
||||
} else { \
|
||||
DCHECK(space_number == CODE_SPACE); \
|
||||
Cell* cell = Cell::cast(new_object); \
|
||||
new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \
|
||||
} \
|
||||
@ -575,6 +574,9 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
// pointer because it points at the entry point, not at the start of the
|
||||
// code object.
|
||||
SINGLE_CASE(kNewObject, kPlain, kInnerPointer, CODE_SPACE)
|
||||
// Support for pointers into a cell. It's an inner pointer because it
|
||||
// points directly at the value field, not the start of the cell object.
|
||||
SINGLE_CASE(kNewObject, kPlain, kInnerPointer, OLD_SPACE)
|
||||
// Deserialize a new code object and write a pointer to its first
|
||||
// instruction to the current code object.
|
||||
ALL_SPACES(kNewObject, kFromCode, kInnerPointer)
|
||||
@ -601,8 +603,12 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
// object.
|
||||
ALL_SPACES(kBackref, kFromCode, kInnerPointer)
|
||||
ALL_SPACES(kBackrefWithSkip, kFromCode, kInnerPointer)
|
||||
ALL_SPACES(kBackref, kPlain, kInnerPointer)
|
||||
ALL_SPACES(kBackrefWithSkip, kPlain, kInnerPointer)
|
||||
// Support for direct instruction pointers in functions.
|
||||
SINGLE_CASE(kBackref, kPlain, kInnerPointer, CODE_SPACE)
|
||||
SINGLE_CASE(kBackrefWithSkip, kPlain, kInnerPointer, CODE_SPACE)
|
||||
// Support for pointers into a cell.
|
||||
SINGLE_CASE(kBackref, kPlain, kInnerPointer, OLD_SPACE)
|
||||
SINGLE_CASE(kBackrefWithSkip, kPlain, kInnerPointer, OLD_SPACE)
|
||||
// Find an object in the roots array and write a pointer to it to the
|
||||
// current object.
|
||||
SINGLE_CASE(kRootArray, kPlain, kStartOfObject, 0)
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "src/compilation-cache.h"
|
||||
#include "src/debug/debug.h"
|
||||
#include "src/heap/spaces.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
@ -1833,6 +1834,55 @@ TEST(Regress503552) {
|
||||
delete script_data;
|
||||
}
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
TEST(CodeSerializerCell) {
|
||||
FLAG_serialize_toplevel = true;
|
||||
LocalContext context;
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
|
||||
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
Assembler::kMinimalBufferSize, &actual_size, true));
|
||||
CHECK(buffer);
|
||||
HandleScope handles(isolate);
|
||||
|
||||
MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
|
||||
v8::internal::CodeObjectRequired::kYes);
|
||||
assembler.enable_serializer();
|
||||
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(0.3);
|
||||
CHECK(isolate->heap()->InNewSpace(*number));
|
||||
MacroAssembler* masm = &assembler;
|
||||
masm->MoveHeapObject(rax, number);
|
||||
masm->ret(0);
|
||||
CodeDesc desc;
|
||||
masm->GetCode(&desc);
|
||||
Handle<Code> code = isolate->factory()->NewCode(
|
||||
desc, Code::ComputeFlags(Code::FUNCTION), masm->CodeObject());
|
||||
code->set_has_reloc_info_for_serialization(true);
|
||||
|
||||
RelocIterator rit1(*code, 1 << RelocInfo::CELL);
|
||||
CHECK_EQ(*number, rit1.rinfo()->target_cell()->value());
|
||||
|
||||
Handle<String> source = isolate->factory()->empty_string();
|
||||
Handle<SharedFunctionInfo> sfi =
|
||||
isolate->factory()->NewSharedFunctionInfo(source, code, false);
|
||||
ScriptData* script_data = CodeSerializer::Serialize(isolate, sfi, source);
|
||||
|
||||
Handle<SharedFunctionInfo> copy =
|
||||
CodeSerializer::Deserialize(isolate, script_data, source)
|
||||
.ToHandleChecked();
|
||||
RelocIterator rit2(copy->code(), 1 << RelocInfo::CELL);
|
||||
CHECK(rit2.rinfo()->target_cell()->IsCell());
|
||||
Handle<Cell> cell(rit2.rinfo()->target_cell());
|
||||
CHECK(cell->value()->IsHeapNumber());
|
||||
CHECK_EQ(0.3, HeapNumber::cast(cell->value())->value());
|
||||
|
||||
delete script_data;
|
||||
}
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
|
||||
TEST(SerializationMemoryStats) {
|
||||
FLAG_profile_deserialization = true;
|
||||
|
Loading…
Reference in New Issue
Block a user