[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:
yangguo 2016-05-19 06:09:06 -07:00 committed by Commit bot
parent c57cadfa09
commit 806739279a
2 changed files with 61 additions and 5 deletions

View File

@ -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)

View File

@ -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;