Do not dump user source code in the code serializer.
R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/390303002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22403 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2aad6f0024
commit
ed744ffa17
@ -973,17 +973,6 @@ class ExternalReference BASE_EMBEDDED {
|
||||
explicit ExternalReference(void* address)
|
||||
: address_(address) {}
|
||||
|
||||
static void* Redirect(Isolate* isolate,
|
||||
void* address,
|
||||
Type type = ExternalReference::BUILTIN_CALL) {
|
||||
ExternalReferenceRedirector* redirector =
|
||||
reinterpret_cast<ExternalReferenceRedirector*>(
|
||||
isolate->external_reference_redirector());
|
||||
if (redirector == NULL) return address;
|
||||
void* answer = (*redirector)(address, type);
|
||||
return answer;
|
||||
}
|
||||
|
||||
static void* Redirect(Isolate* isolate,
|
||||
Address address_arg,
|
||||
Type type = ExternalReference::BUILTIN_CALL) {
|
||||
|
@ -967,8 +967,7 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
|
||||
is_shared_cross_origin, context);
|
||||
if (maybe_result.is_null() && FLAG_serialize_toplevel &&
|
||||
cached_data_mode == CONSUME_CACHED_DATA) {
|
||||
Object* des = CodeSerializer::Deserialize(isolate, *cached_data);
|
||||
return handle(SharedFunctionInfo::cast(des), isolate);
|
||||
return CodeSerializer::Deserialize(isolate, *cached_data, source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1002,7 +1001,7 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
|
||||
if (extension == NULL && !result.is_null() && !result->dont_cache()) {
|
||||
compilation_cache->PutScript(source, context, result);
|
||||
if (FLAG_serialize_toplevel && cached_data_mode == PRODUCE_CACHED_DATA) {
|
||||
*cached_data = CodeSerializer::Serialize(result);
|
||||
*cached_data = CodeSerializer::Serialize(isolate, result, source);
|
||||
}
|
||||
}
|
||||
if (result.is_null()) isolate->ReportPendingMessages();
|
||||
|
@ -718,7 +718,7 @@ class CodeAddressMap: public CodeEventLogger {
|
||||
|
||||
Deserializer::Deserializer(SnapshotByteSource* source)
|
||||
: isolate_(NULL),
|
||||
deserialize_code_(false),
|
||||
attached_objects_(NULL),
|
||||
source_(source),
|
||||
external_reference_decoder_(NULL) {
|
||||
for (int i = 0; i < LAST_SPACE + 1; i++) {
|
||||
@ -905,7 +905,7 @@ void Deserializer::ReadObject(int space_number,
|
||||
if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
|
||||
|
||||
// Fix up strings from serialized user code.
|
||||
if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj);
|
||||
if (deserializing_user_code()) obj = ProcessObjectFromSerializedCode(obj);
|
||||
|
||||
*write_back = obj;
|
||||
#ifdef DEBUG
|
||||
@ -971,13 +971,18 @@ void Deserializer::ReadChunk(Object** current,
|
||||
emit_write_barrier = (space_number == NEW_SPACE); \
|
||||
new_object = GetAddressFromEnd(data & kSpaceMask); \
|
||||
} else if (where == kBuiltin) { \
|
||||
ASSERT(deserialize_code_); \
|
||||
ASSERT(deserializing_user_code()); \
|
||||
int builtin_id = source_->GetInt(); \
|
||||
ASSERT_LE(0, builtin_id); \
|
||||
ASSERT_LT(builtin_id, Builtins::builtin_count); \
|
||||
Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
|
||||
new_object = isolate->builtins()->builtin(name); \
|
||||
emit_write_barrier = false; \
|
||||
} else if (where == kAttachedReference) { \
|
||||
ASSERT(deserializing_user_code()); \
|
||||
int index = source_->GetInt(); \
|
||||
new_object = attached_objects_->at(index); \
|
||||
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
||||
} else { \
|
||||
ASSERT(where == kBackrefWithSkip); \
|
||||
int skip = source_->GetInt(); \
|
||||
@ -1222,6 +1227,10 @@ void Deserializer::ReadChunk(Object** current,
|
||||
// Find a builtin and write a pointer to it in the current code object.
|
||||
CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
|
||||
CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
|
||||
// Find an object in the attached references and write a pointer to it to
|
||||
// the current object.
|
||||
CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0)
|
||||
CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0)
|
||||
|
||||
#undef CASE_STATEMENT
|
||||
#undef CASE_BODY
|
||||
@ -1875,12 +1884,13 @@ void Serializer::InitializeCodeAddressMap() {
|
||||
}
|
||||
|
||||
|
||||
ScriptData* CodeSerializer::Serialize(Handle<SharedFunctionInfo> info) {
|
||||
ScriptData* CodeSerializer::Serialize(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> info,
|
||||
Handle<String> source) {
|
||||
// Serialize code object.
|
||||
List<byte> payload;
|
||||
ListSnapshotSink list_sink(&payload);
|
||||
CodeSerializer cs(info->GetIsolate(), &list_sink);
|
||||
DisallowHeapAllocation no_gc;
|
||||
CodeSerializer cs(isolate, &list_sink, *source);
|
||||
Object** location = Handle<Object>::cast(info).location();
|
||||
cs.VisitPointer(location);
|
||||
cs.Pad();
|
||||
@ -1908,10 +1918,18 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
||||
}
|
||||
|
||||
// TODO(yangguo) wire up stubs from stub cache.
|
||||
// TODO(yangguo) wire up script source.
|
||||
// TODO(yangguo) wire up global object.
|
||||
// TODO(yangguo) We cannot deal with different hash seeds yet.
|
||||
ASSERT(!heap_object->IsHashTable());
|
||||
|
||||
if (address_mapper_.IsMapped(heap_object)) {
|
||||
int space = SpaceOfObject(heap_object);
|
||||
int address = address_mapper_.MappedTo(heap_object);
|
||||
SerializeReferenceToPreviousObject(space, address, how_to_code,
|
||||
where_to_point, skip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (heap_object->IsCode()) {
|
||||
Code* code_object = Code::cast(heap_object);
|
||||
if (code_object->kind() == Code::BUILTIN) {
|
||||
@ -1920,11 +1938,8 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
||||
}
|
||||
}
|
||||
|
||||
if (address_mapper_.IsMapped(heap_object)) {
|
||||
int space = SpaceOfObject(heap_object);
|
||||
int address = address_mapper_.MappedTo(heap_object);
|
||||
SerializeReferenceToPreviousObject(space, address, how_to_code,
|
||||
where_to_point, skip);
|
||||
if (heap_object == source_) {
|
||||
SerializeSourceObject(how_to_code, where_to_point, skip);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1960,21 +1975,42 @@ void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
|
||||
}
|
||||
|
||||
|
||||
Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
|
||||
void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
|
||||
WhereToPoint where_to_point,
|
||||
int skip) {
|
||||
if (skip != 0) {
|
||||
sink_->Put(kSkip, "SkipFromSerializeSourceObject");
|
||||
sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
|
||||
}
|
||||
|
||||
ASSERT(how_to_code == kPlain && where_to_point == kStartOfObject);
|
||||
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
|
||||
sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
|
||||
}
|
||||
|
||||
|
||||
Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
|
||||
ScriptData* data,
|
||||
Handle<String> source) {
|
||||
SerializedCodeData scd(data);
|
||||
SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
|
||||
Deserializer deserializer(&payload);
|
||||
deserializer.ExpectSerializedCode();
|
||||
STATIC_ASSERT(NEW_SPACE == 0);
|
||||
// TODO(yangguo) what happens if remaining new space is too small?
|
||||
for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
|
||||
deserializer.set_reservation(i, scd.GetReservation(i));
|
||||
}
|
||||
DisallowHeapAllocation no_gc;
|
||||
|
||||
// Prepare and register list of attached objects.
|
||||
List<Object*> attached_objects(1);
|
||||
attached_objects.Set(kSourceObjectIndex, *source);
|
||||
deserializer.SetAttachedObjects(&attached_objects);
|
||||
|
||||
Object* root;
|
||||
deserializer.DeserializePartial(isolate, &root);
|
||||
deserializer.FlushICacheForNewCodeObjects();
|
||||
ASSERT(root->IsSharedFunctionInfo());
|
||||
return root;
|
||||
return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate);
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,9 +155,9 @@ class SerializerDeserializer: public ObjectVisitor {
|
||||
kExternalReference = 0xb, // Pointer to an external reference.
|
||||
kSkip = 0xc, // Skip n bytes.
|
||||
kBuiltin = 0xd, // Builtin code object.
|
||||
// 0xe Free.
|
||||
kNop = 0xf, // Does nothing, used to pad.
|
||||
kBackref = 0x10, // Object is described relative to end.
|
||||
kAttachedReference = 0xe, // Object is described in an attached list.
|
||||
kNop = 0xf, // Does nothing, used to pad.
|
||||
kBackref = 0x10, // Object is described relative to end.
|
||||
// 0x11-0x16 One per space.
|
||||
kBackrefWithSkip = 0x18, // Object is described relative to end.
|
||||
// 0x19-0x1e One per space.
|
||||
@ -252,9 +252,13 @@ class Deserializer: public SerializerDeserializer {
|
||||
|
||||
void FlushICacheForNewCodeObjects();
|
||||
|
||||
// Call this to indicate that the serialized data represents user code.
|
||||
// There are some more wiring up required in this case.
|
||||
void ExpectSerializedCode() { deserialize_code_ = true; }
|
||||
// Serialized user code reference certain objects that are provided in a list
|
||||
// By calling this method, we assume that we are deserializing user code.
|
||||
void SetAttachedObjects(List<Object*>* attached_objects) {
|
||||
attached_objects_ = attached_objects;
|
||||
}
|
||||
|
||||
bool deserializing_user_code() { return attached_objects_ != NULL; }
|
||||
|
||||
private:
|
||||
virtual void VisitPointers(Object** start, Object** end);
|
||||
@ -297,7 +301,9 @@ class Deserializer: public SerializerDeserializer {
|
||||
|
||||
// Cached current isolate.
|
||||
Isolate* isolate_;
|
||||
bool deserialize_code_;
|
||||
|
||||
// Objects from the attached object descriptions in the serialized user code.
|
||||
List<Object*>* attached_objects_;
|
||||
|
||||
SnapshotByteSource* source_;
|
||||
// This is the address of the next object that will be allocated in each
|
||||
@ -557,26 +563,42 @@ class StartupSerializer : public Serializer {
|
||||
SerializeWeakReferences();
|
||||
Pad();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(StartupSerializer);
|
||||
};
|
||||
|
||||
|
||||
class CodeSerializer : public Serializer {
|
||||
public:
|
||||
CodeSerializer(Isolate* isolate, SnapshotByteSink* sink)
|
||||
: Serializer(isolate, sink) {
|
||||
CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source)
|
||||
: Serializer(isolate, sink), source_(source) {
|
||||
set_root_index_wave_front(Heap::kStrongRootListLength);
|
||||
InitializeCodeAddressMap();
|
||||
}
|
||||
|
||||
static ScriptData* Serialize(Handle<SharedFunctionInfo> info);
|
||||
static ScriptData* Serialize(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> info,
|
||||
Handle<String> source);
|
||||
|
||||
virtual void SerializeObject(Object* o, HowToCode how_to_code,
|
||||
WhereToPoint where_to_point, int skip);
|
||||
|
||||
static Object* Deserialize(Isolate* isolate, ScriptData* data);
|
||||
static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
|
||||
ScriptData* data,
|
||||
Handle<String> source);
|
||||
|
||||
static const int kSourceObjectIndex = 0;
|
||||
|
||||
private:
|
||||
void SerializeBuiltin(Code* builtin, HowToCode how_to_code,
|
||||
WhereToPoint where_to_point, int skip);
|
||||
void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point,
|
||||
int skip);
|
||||
|
||||
DisallowHeapAllocation no_gc_;
|
||||
String* source_;
|
||||
DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
|
||||
};
|
||||
|
||||
|
||||
|
@ -707,6 +707,8 @@ TEST(SerializeToplevelOnePlusOne) {
|
||||
&cache, CONSUME_CACHED_DATA, NOT_NATIVES_CODE);
|
||||
|
||||
CHECK_NE(*orig, *copy);
|
||||
CHECK(Script::cast(copy->script())->source() == *source2_string);
|
||||
|
||||
Handle<JSFunction> copy_fun =
|
||||
isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
||||
copy, isolate->native_context());
|
||||
@ -758,6 +760,8 @@ TEST(SerializeToplevelInternalizedString) {
|
||||
Handle<Context>(isolate->native_context()), NULL,
|
||||
&cache, CONSUME_CACHED_DATA, NOT_NATIVES_CODE);
|
||||
CHECK_NE(*orig, *copy);
|
||||
CHECK(Script::cast(copy->script())->source() == *source2_string);
|
||||
|
||||
Handle<JSFunction> copy_fun =
|
||||
isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
||||
copy, isolate->native_context());
|
||||
|
Loading…
Reference in New Issue
Block a user