SnapshotByteSink* sink = FLAG_trace_code_serializer
? static_cast<SnapshotByteSink*>(&debug_sink)
: static_cast<SnapshotByteSink*>(&list_sink);
- CodeSerializer cs(isolate, sink, *source);
+ CodeSerializer cs(isolate, sink, *source, info->code());
DisallowHeapAllocation no_gc;
Object** location = Handle<Object>::cast(info).location();
cs.VisitPointer(location);
void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
- CHECK(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o);
- // The code-caches link to context-specific code objects, which
- // the startup and context serializes cannot currently handle.
- DCHECK(!heap_object->IsMap() ||
- Map::cast(heap_object)->code_cache() ==
- heap_object->GetHeap()->empty_fixed_array());
-
int root_index;
if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
return;
}
- // TODO(yangguo) wire up global object.
- // TODO(yangguo) We cannot deal with different hash seeds yet.
- DCHECK(!heap_object->IsHashTable());
-
if (address_mapper_.IsMapped(heap_object)) {
SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
skip);
return;
}
+ if (skip != 0) {
+ sink_->Put(kSkip, "SkipFromSerializeObject");
+ sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
+ }
+
if (heap_object->IsCode()) {
Code* code_object = Code::cast(heap_object);
switch (code_object->kind()) {
case Code::NUMBER_OF_KINDS: // Pseudo enum value.
CHECK(false);
case Code::BUILTIN:
- SerializeBuiltin(code_object, how_to_code, where_to_point, skip);
+ SerializeBuiltin(code_object, how_to_code, where_to_point);
return;
case Code::STUB:
- SerializeCodeStub(code_object, how_to_code, where_to_point, skip);
+ SerializeCodeStub(code_object, how_to_code, where_to_point);
return;
#define IC_KIND_CASE(KIND) case Code::KIND:
IC_KIND_LIST(IC_KIND_CASE)
#undef IC_KIND_CASE
+ SerializeHeapObject(code_object, how_to_code, where_to_point);
+ return;
// TODO(yangguo): add special handling to canonicalize ICs.
case Code::FUNCTION:
- SerializeHeapObject(code_object, how_to_code, where_to_point, skip);
+ // Only serialize the code for the toplevel function. Replace code
+ // of included function literals by the lazy compile builtin.
+ // This is safe, as checked in Compiler::BuildFunctionInfo.
+ if (code_object != main_code_) {
+ Code* lazy = *isolate()->builtins()->CompileLazy();
+ SerializeBuiltin(lazy, how_to_code, where_to_point);
+ } else {
+ SerializeHeapObject(code_object, how_to_code, where_to_point);
+ }
return;
}
}
if (heap_object == source_) {
- SerializeSourceObject(how_to_code, where_to_point, skip);
+ SerializeSourceObject(how_to_code, where_to_point);
return;
}
- SerializeHeapObject(heap_object, how_to_code, where_to_point, skip);
+ // Past this point we should not see any (context-specific) maps anymore.
+ CHECK(!heap_object->IsMap());
+ // There should be no references to the global object embedded.
+ CHECK(!heap_object->IsJSGlobalProxy() && !heap_object->IsGlobalObject());
+ // There should be no hash table embedded. They would require rehashing.
+ CHECK(!heap_object->IsHashTable());
+
+ SerializeHeapObject(heap_object, how_to_code, where_to_point);
}
void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
HowToCode how_to_code,
- WhereToPoint where_to_point,
- int skip) {
+ WhereToPoint where_to_point) {
if (heap_object->IsScript()) {
// The wrapper cache uses a Foreign object to point to a global handle.
// However, the object visitor expects foreign objects to point to external
Script::cast(heap_object)->ClearWrapperCache();
}
- if (skip != 0) {
- sink_->Put(kSkip, "SkipFromSerializeObject");
- sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
- }
-
if (FLAG_trace_code_serializer) {
PrintF("Encoding heap object: ");
heap_object->ShortPrint();
void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip) {
- if (skip != 0) {
- sink_->Put(kSkip, "SkipFromSerializeBuiltin");
- sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
- }
-
+ WhereToPoint where_to_point) {
DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
(how_to_code == kPlain && where_to_point == kInnerPointer) ||
(how_to_code == kFromCode && where_to_point == kInnerPointer));
void CodeSerializer::SerializeCodeStub(Code* stub, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip) {
+ WhereToPoint where_to_point) {
DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
(how_to_code == kPlain && where_to_point == kInnerPointer) ||
(how_to_code == kFromCode && where_to_point == kInnerPointer));
uint32_t stub_key = stub->stub_key();
DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache);
- if (skip != 0) {
- sink_->Put(kSkip, "SkipFromSerializeCodeStub");
- sink_->PutInt(skip, "SkipDistanceFromSerializeCodeStub");
- }
-
int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
if (FLAG_trace_code_serializer) {
void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
- WhereToPoint where_to_point,
- int skip) {
- if (skip != 0) {
- sink_->Put(kSkip, "SkipFromSerializeSourceObject");
- sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
- }
-
- if (FLAG_trace_code_serializer) {
- PrintF("Encoding source object\n");
- }
+ WhereToPoint where_to_point) {
+ if (FLAG_trace_code_serializer) PrintF("Encoding source object\n");
DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
class CodeSerializer : public Serializer {
public:
- CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source)
- : Serializer(isolate, sink), source_(source) {
- set_root_index_wave_front(Heap::kStrongRootListLength);
- InitializeCodeAddressMap();
- }
-
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 Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
ScriptData* data,
Handle<String> source);
List<uint32_t>* stub_keys() { return &stub_keys_; }
private:
+ CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source,
+ Code* main_code)
+ : Serializer(isolate, sink), source_(source), main_code_(main_code) {
+ set_root_index_wave_front(Heap::kStrongRootListLength);
+ InitializeCodeAddressMap();
+ }
+
+ virtual void SerializeObject(Object* o, HowToCode how_to_code,
+ WhereToPoint where_to_point, int skip);
+
void SerializeBuiltin(Code* builtin, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip);
+ WhereToPoint where_to_point);
void SerializeCodeStub(Code* stub, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip);
- void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point,
- int skip);
+ WhereToPoint where_to_point);
+ void SerializeSourceObject(HowToCode how_to_code,
+ WhereToPoint where_to_point);
void SerializeHeapObject(HeapObject* heap_object, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip);
+ WhereToPoint where_to_point);
int AddCodeStubKey(uint32_t stub_key);
DisallowHeapAllocation no_gc_;
String* source_;
+ Code* main_code_;
List<uint32_t> stub_keys_;
DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
};