Commit ad24cdae authored by yangguo@chromium.org's avatar yangguo@chromium.org

Do not serialize non-lazy compiled function literals.

... and some small refactorings.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/594513002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24266 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0ae4c7d6
...@@ -995,6 +995,8 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -995,6 +995,8 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
DCHECK(info->is_eval() || info->is_global()); DCHECK(info->is_eval() || info->is_global());
info->MarkAsToplevel();
Handle<SharedFunctionInfo> result; Handle<SharedFunctionInfo> result;
{ VMState<COMPILER> state(info->isolate()); { VMState<COMPILER> state(info->isolate());
...@@ -1264,6 +1266,13 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( ...@@ -1264,6 +1266,13 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
bool allow_lazy = literal->AllowsLazyCompilation() && bool allow_lazy = literal->AllowsLazyCompilation() &&
!DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
if (outer_info->is_toplevel() && outer_info->will_serialize()) {
// Make sure that if the toplevel code (possibly to be serialized),
// the inner unction must be allowed to be compiled lazily.
DCHECK(allow_lazy);
}
// Generate code // Generate code
Handle<ScopeInfo> scope_info; Handle<ScopeInfo> scope_info;
if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
......
...@@ -85,7 +85,8 @@ class CompilationInfo { ...@@ -85,7 +85,8 @@ class CompilationInfo {
kInliningEnabled = 1 << 17, kInliningEnabled = 1 << 17,
kTypingEnabled = 1 << 18, kTypingEnabled = 1 << 18,
kDisableFutureOptimization = 1 << 19, kDisableFutureOptimization = 1 << 19,
kAbortedDueToDependency = 1 << 20 kAbortedDueToDependency = 1 << 20,
kToplevel = 1 << 21
}; };
CompilationInfo(Handle<JSFunction> closure, Zone* zone); CompilationInfo(Handle<JSFunction> closure, Zone* zone);
...@@ -208,6 +209,10 @@ class CompilationInfo { ...@@ -208,6 +209,10 @@ class CompilationInfo {
bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } bool is_typing_enabled() const { return GetFlag(kTypingEnabled); }
void MarkAsToplevel() { SetFlag(kToplevel); }
bool is_toplevel() const { return GetFlag(kToplevel); }
bool IsCodePreAgingActive() const { bool IsCodePreAgingActive() const {
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
!is_debug(); !is_debug();
......
...@@ -1846,7 +1846,7 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate, ...@@ -1846,7 +1846,7 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
SnapshotByteSink* sink = FLAG_trace_code_serializer SnapshotByteSink* sink = FLAG_trace_code_serializer
? static_cast<SnapshotByteSink*>(&debug_sink) ? static_cast<SnapshotByteSink*>(&debug_sink)
: static_cast<SnapshotByteSink*>(&list_sink); : static_cast<SnapshotByteSink*>(&list_sink);
CodeSerializer cs(isolate, sink, *source); CodeSerializer cs(isolate, sink, *source, info->code());
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Object** location = Handle<Object>::cast(info).location(); Object** location = Handle<Object>::cast(info).location();
cs.VisitPointer(location); cs.VisitPointer(location);
...@@ -1867,31 +1867,25 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate, ...@@ -1867,31 +1867,25 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) { WhereToPoint where_to_point, int skip) {
CHECK(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o); 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; int root_index;
if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
return; 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)) { if (address_mapper_.IsMapped(heap_object)) {
SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
skip); skip);
return; return;
} }
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeObject");
sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
}
if (heap_object->IsCode()) { if (heap_object->IsCode()) {
Code* code_object = Code::cast(heap_object); Code* code_object = Code::cast(heap_object);
switch (code_object->kind()) { switch (code_object->kind()) {
...@@ -1901,34 +1895,50 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, ...@@ -1901,34 +1895,50 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
case Code::NUMBER_OF_KINDS: // Pseudo enum value. case Code::NUMBER_OF_KINDS: // Pseudo enum value.
CHECK(false); CHECK(false);
case Code::BUILTIN: case Code::BUILTIN:
SerializeBuiltin(code_object, how_to_code, where_to_point, skip); SerializeBuiltin(code_object, how_to_code, where_to_point);
return; return;
case Code::STUB: case Code::STUB:
SerializeCodeStub(code_object, how_to_code, where_to_point, skip); SerializeCodeStub(code_object, how_to_code, where_to_point);
return; return;
#define IC_KIND_CASE(KIND) case Code::KIND: #define IC_KIND_CASE(KIND) case Code::KIND:
IC_KIND_LIST(IC_KIND_CASE) IC_KIND_LIST(IC_KIND_CASE)
#undef 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. // TODO(yangguo): add special handling to canonicalize ICs.
case Code::FUNCTION: 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; return;
} }
} }
if (heap_object == source_) { if (heap_object == source_) {
SerializeSourceObject(how_to_code, where_to_point, skip); SerializeSourceObject(how_to_code, where_to_point);
return; 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, void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
HowToCode how_to_code, HowToCode how_to_code,
WhereToPoint where_to_point, WhereToPoint where_to_point) {
int skip) {
if (heap_object->IsScript()) { if (heap_object->IsScript()) {
// The wrapper cache uses a Foreign object to point to a global handle. // The wrapper cache uses a Foreign object to point to a global handle.
// However, the object visitor expects foreign objects to point to external // However, the object visitor expects foreign objects to point to external
...@@ -1936,11 +1946,6 @@ void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, ...@@ -1936,11 +1946,6 @@ void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
Script::cast(heap_object)->ClearWrapperCache(); Script::cast(heap_object)->ClearWrapperCache();
} }
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeObject");
sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
}
if (FLAG_trace_code_serializer) { if (FLAG_trace_code_serializer) {
PrintF("Encoding heap object: "); PrintF("Encoding heap object: ");
heap_object->ShortPrint(); heap_object->ShortPrint();
...@@ -1955,12 +1960,7 @@ void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, ...@@ -1955,12 +1960,7 @@ void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code, void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) { WhereToPoint where_to_point) {
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeBuiltin");
sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
}
DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
(how_to_code == kPlain && where_to_point == kInnerPointer) || (how_to_code == kPlain && where_to_point == kInnerPointer) ||
(how_to_code == kFromCode && where_to_point == kInnerPointer)); (how_to_code == kFromCode && where_to_point == kInnerPointer));
...@@ -1979,18 +1979,13 @@ void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code, ...@@ -1979,18 +1979,13 @@ void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
void CodeSerializer::SerializeCodeStub(Code* stub, HowToCode how_to_code, 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) || DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
(how_to_code == kPlain && where_to_point == kInnerPointer) || (how_to_code == kPlain && where_to_point == kInnerPointer) ||
(how_to_code == kFromCode && where_to_point == kInnerPointer)); (how_to_code == kFromCode && where_to_point == kInnerPointer));
uint32_t stub_key = stub->stub_key(); uint32_t stub_key = stub->stub_key();
DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache);
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeCodeStub");
sink_->PutInt(skip, "SkipDistanceFromSerializeCodeStub");
}
int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
if (FLAG_trace_code_serializer) { if (FLAG_trace_code_serializer) {
...@@ -2017,16 +2012,8 @@ int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { ...@@ -2017,16 +2012,8 @@ int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
WhereToPoint where_to_point, WhereToPoint where_to_point) {
int skip) { if (FLAG_trace_code_serializer) PrintF("Encoding source object\n");
if (skip != 0) {
sink_->Put(kSkip, "SkipFromSerializeSourceObject");
sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
}
if (FLAG_trace_code_serializer) {
PrintF("Encoding source object\n");
}
DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
......
...@@ -577,19 +577,10 @@ class StartupSerializer : public Serializer { ...@@ -577,19 +577,10 @@ class StartupSerializer : public Serializer {
class CodeSerializer : public Serializer { class CodeSerializer : public Serializer {
public: 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, static ScriptData* Serialize(Isolate* isolate,
Handle<SharedFunctionInfo> info, Handle<SharedFunctionInfo> info,
Handle<String> source); Handle<String> source);
virtual void SerializeObject(Object* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate, static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
ScriptData* data, ScriptData* data,
Handle<String> source); Handle<String> source);
...@@ -605,18 +596,29 @@ class CodeSerializer : public Serializer { ...@@ -605,18 +596,29 @@ class CodeSerializer : public Serializer {
List<uint32_t>* stub_keys() { return &stub_keys_; } List<uint32_t>* stub_keys() { return &stub_keys_; }
private: 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, 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, void SerializeCodeStub(Code* stub, 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 SerializeSourceObject(HowToCode how_to_code,
int skip); WhereToPoint where_to_point);
void SerializeHeapObject(HeapObject* heap_object, HowToCode how_to_code, 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); int AddCodeStubKey(uint32_t stub_key);
DisallowHeapAllocation no_gc_; DisallowHeapAllocation no_gc_;
String* source_; String* source_;
Code* main_code_;
List<uint32_t> stub_keys_; List<uint32_t> stub_keys_;
DISALLOW_COPY_AND_ASSIGN(CodeSerializer); DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment