Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/compiler.cc

Issue 366153002: Add script streaming API (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: special chars fix Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« include/v8.h ('K') | « src/compiler.h ('k') | src/isolate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 26 matching lines...) Expand all
37 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { 37 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
38 byte* copy = NewArray<byte>(length); 38 byte* copy = NewArray<byte>(length);
39 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); 39 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
40 CopyBytes(copy, data, length); 40 CopyBytes(copy, data, length);
41 data_ = copy; 41 data_ = copy;
42 AcquireDataOwnership(); 42 AcquireDataOwnership();
43 } 43 }
44 } 44 }
45 45
46 46
47 CompilationInfo::CompilationInfo(Handle<Script> script, 47 CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone)
48 Zone* zone)
49 : flags_(StrictModeField::encode(SLOPPY)), 48 : flags_(StrictModeField::encode(SLOPPY)),
50 script_(script), 49 script_(script),
50 source_stream_(NULL),
51 osr_ast_id_(BailoutId::None()), 51 osr_ast_id_(BailoutId::None()),
52 parameter_count_(0), 52 parameter_count_(0),
53 this_has_uses_(true), 53 this_has_uses_(true),
54 optimization_id_(-1), 54 optimization_id_(-1),
55 ast_value_factory_(NULL), 55 ast_value_factory_(NULL),
56 ast_value_factory_owned_(false) { 56 ast_value_factory_owned_(false) {
57 Initialize(script->GetIsolate(), BASE, zone); 57 Initialize(script->GetIsolate(), BASE, zone);
58 } 58 }
59 59
60 60
61 CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone) 61 CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone)
62 : flags_(StrictModeField::encode(SLOPPY)), 62 : flags_(StrictModeField::encode(SLOPPY)),
63 script_(Handle<Script>::null()), 63 script_(Handle<Script>::null()),
64 osr_ast_id_(BailoutId::None()), 64 osr_ast_id_(BailoutId::None()),
65 parameter_count_(0), 65 parameter_count_(0),
66 this_has_uses_(true), 66 this_has_uses_(true),
67 optimization_id_(-1), 67 optimization_id_(-1),
68 ast_value_factory_(NULL), 68 ast_value_factory_(NULL),
69 ast_value_factory_owned_(false) { 69 ast_value_factory_owned_(false) {
70 Initialize(isolate, STUB, zone); 70 Initialize(isolate, STUB, zone);
71 } 71 }
72 72
73 73
74 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, 74 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
75 Zone* zone) 75 Zone* zone)
76 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)), 76 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
77 shared_info_(shared_info), 77 shared_info_(shared_info),
78 script_(Handle<Script>(Script::cast(shared_info->script()))), 78 script_(Handle<Script>(Script::cast(shared_info->script()))),
79 source_stream_(NULL),
79 osr_ast_id_(BailoutId::None()), 80 osr_ast_id_(BailoutId::None()),
80 parameter_count_(0), 81 parameter_count_(0),
81 this_has_uses_(true), 82 this_has_uses_(true),
82 optimization_id_(-1), 83 optimization_id_(-1),
83 ast_value_factory_(NULL), 84 ast_value_factory_(NULL),
84 ast_value_factory_owned_(false) { 85 ast_value_factory_owned_(false) {
85 Initialize(script_->GetIsolate(), BASE, zone); 86 Initialize(script_->GetIsolate(), BASE, zone);
86 } 87 }
87 88
88 89
89 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, 90 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone)
90 Zone* zone)
91 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)), 91 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
92 closure_(closure), 92 closure_(closure),
93 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 93 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
94 script_(Handle<Script>(Script::cast(shared_info_->script()))), 94 script_(Handle<Script>(Script::cast(shared_info_->script()))),
95 source_stream_(NULL),
95 context_(closure->context()), 96 context_(closure->context()),
96 osr_ast_id_(BailoutId::None()), 97 osr_ast_id_(BailoutId::None()),
97 parameter_count_(0), 98 parameter_count_(0),
98 this_has_uses_(true), 99 this_has_uses_(true),
99 optimization_id_(-1), 100 optimization_id_(-1),
100 ast_value_factory_(NULL), 101 ast_value_factory_(NULL),
101 ast_value_factory_owned_(false) { 102 ast_value_factory_owned_(false) {
102 Initialize(script_->GetIsolate(), BASE, zone); 103 Initialize(script_->GetIsolate(), BASE, zone);
103 } 104 }
104 105
105 106
106 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, 107 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate,
107 Isolate* isolate,
108 Zone* zone) 108 Zone* zone)
109 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)), 109 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
110 source_stream_(NULL),
110 osr_ast_id_(BailoutId::None()), 111 osr_ast_id_(BailoutId::None()),
111 parameter_count_(0), 112 parameter_count_(0),
112 this_has_uses_(true), 113 this_has_uses_(true),
113 optimization_id_(-1), 114 optimization_id_(-1),
114 ast_value_factory_(NULL), 115 ast_value_factory_(NULL),
115 ast_value_factory_owned_(false) { 116 ast_value_factory_owned_(false) {
116 Initialize(isolate, STUB, zone); 117 Initialize(isolate, STUB, zone);
117 code_stub_ = stub; 118 code_stub_ = stub;
118 } 119 }
119 120
120 121
122 CompilationInfo::CompilationInfo(ExternalSourceStream* stream, Isolate* isolate,
123 Zone* zone)
124 : flags_(StrictModeField::encode(SLOPPY)),
125 source_stream_(stream),
126 osr_ast_id_(BailoutId::None()),
127 parameter_count_(0),
128 this_has_uses_(true),
129 optimization_id_(-1),
130 ast_value_factory_(NULL),
131 ast_value_factory_owned_(false) {
132 Initialize(isolate, BASE, zone);
133 }
134
135
121 void CompilationInfo::Initialize(Isolate* isolate, 136 void CompilationInfo::Initialize(Isolate* isolate,
122 Mode mode, 137 Mode mode,
123 Zone* zone) { 138 Zone* zone) {
124 isolate_ = isolate; 139 isolate_ = isolate;
125 function_ = NULL; 140 function_ = NULL;
126 scope_ = NULL; 141 scope_ = NULL;
127 global_scope_ = NULL; 142 global_scope_ = NULL;
128 extension_ = NULL; 143 extension_ = NULL;
129 cached_data_ = NULL; 144 cached_data_ = NULL;
130 compile_options_ = ScriptCompiler::kNoCompileOptions; 145 compile_options_ = ScriptCompiler::kNoCompileOptions;
131 zone_ = zone; 146 zone_ = zone;
132 deferred_handles_ = NULL; 147 deferred_handles_ = NULL;
133 code_stub_ = NULL; 148 code_stub_ = NULL;
134 prologue_offset_ = Code::kPrologueOffsetNotSet; 149 prologue_offset_ = Code::kPrologueOffsetNotSet;
135 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); 150 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
136 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() 151 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
137 ? new List<OffsetRange>(2) : NULL; 152 ? new List<OffsetRange>(2) : NULL;
138 for (int i = 0; i < DependentCode::kGroupCount; i++) { 153 for (int i = 0; i < DependentCode::kGroupCount; i++) {
139 dependencies_[i] = NULL; 154 dependencies_[i] = NULL;
140 } 155 }
141 if (mode == STUB) { 156 if (mode == STUB) {
142 mode_ = STUB; 157 mode_ = STUB;
143 return; 158 return;
144 } 159 }
145 mode_ = mode; 160 mode_ = mode;
146 abort_due_to_dependency_ = false; 161 abort_due_to_dependency_ = false;
147 if (script_->type()->value() == Script::TYPE_NATIVE) MarkAsNative(); 162 if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) {
163 MarkAsNative();
164 }
148 if (isolate_->debug()->is_active()) MarkAsDebug(); 165 if (isolate_->debug()->is_active()) MarkAsDebug();
149 166
150 if (!shared_info_.is_null()) { 167 if (!shared_info_.is_null()) {
151 DCHECK(strict_mode() == SLOPPY); 168 DCHECK(strict_mode() == SLOPPY);
152 SetStrictMode(shared_info_->strict_mode()); 169 SetStrictMode(shared_info_->strict_mode());
153 } 170 }
154 set_bailout_reason(kUnknown); 171 set_bailout_reason(kUnknown);
155 172
156 if (!shared_info().is_null() && shared_info()->is_compiled()) { 173 if (!shared_info().is_null() && shared_info()->is_compiled()) {
157 // We should initialize the CompilationInfo feedback vector from the 174 // We should initialize the CompilationInfo feedback vector from the
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 if (!CompileUnoptimizedCode(&info)) return; 823 if (!CompileUnoptimizedCode(&info)) return;
807 if (!info.shared_info().is_null()) { 824 if (!info.shared_info().is_null()) {
808 Handle<ScopeInfo> scope_info = ScopeInfo::Create(info.scope(), 825 Handle<ScopeInfo> scope_info = ScopeInfo::Create(info.scope(),
809 info.zone()); 826 info.zone());
810 info.shared_info()->set_scope_info(*scope_info); 827 info.shared_info()->set_scope_info(*scope_info);
811 } 828 }
812 tracker.RecordRootFunctionInfo(info.code()); 829 tracker.RecordRootFunctionInfo(info.code());
813 } 830 }
814 831
815 832
816 static bool DebuggerWantsEagerCompilation(CompilationInfo* info,
817 bool allow_lazy_without_ctx = false) {
818 return LiveEditFunctionTracker::IsActive(info->isolate()) ||
819 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
820 }
821
822
823 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { 833 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
824 Isolate* isolate = info->isolate(); 834 Isolate* isolate = info->isolate();
825 PostponeInterruptsScope postpone(isolate); 835 PostponeInterruptsScope postpone(isolate);
826 DCHECK(!isolate->native_context().is_null()); 836 DCHECK(!isolate->native_context().is_null());
827 Handle<Script> script = info->script(); 837 Handle<Script> script = info->script();
828 838
829 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? 839 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
830 FixedArray* array = isolate->native_context()->embedder_data(); 840 FixedArray* array = isolate->native_context()->embedder_data();
831 script->set_context_data(array->get(0)); 841 script->set_context_data(array->get(0));
832 842
833 isolate->debug()->OnBeforeCompile(script); 843 isolate->debug()->OnBeforeCompile(script);
834 844
835 DCHECK(info->is_eval() || info->is_global()); 845 DCHECK(info->is_eval() || info->is_global());
836 846
837 bool parse_allow_lazy =
838 (info->compile_options() == ScriptCompiler::kConsumeParserCache ||
839 String::cast(script->source())->length() > FLAG_min_preparse_length) &&
840 !DebuggerWantsEagerCompilation(info);
841
842 if (!parse_allow_lazy &&
843 (info->compile_options() == ScriptCompiler::kProduceParserCache ||
844 info->compile_options() == ScriptCompiler::kConsumeParserCache)) {
845 // We are going to parse eagerly, but we either 1) have cached data produced
846 // by lazy parsing or 2) are asked to generate cached data. We cannot use
847 // the existing data, since it won't contain all the symbols we need for
848 // eager parsing. In addition, it doesn't make sense to produce the data
849 // when parsing eagerly. That data would contain all symbols, but no
850 // functions, so it cannot be used to aid lazy parsing later.
851 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions);
852 }
853
854 Handle<SharedFunctionInfo> result; 847 Handle<SharedFunctionInfo> result;
855 848
856 { VMState<COMPILER> state(info->isolate()); 849 { VMState<COMPILER> state(info->isolate());
857 if (!Parser::Parse(info, parse_allow_lazy)) { 850 if (info->function() == NULL) {
858 return Handle<SharedFunctionInfo>::null(); 851 // Parse the script if needed (if it's already parsed, function() returns
852 // non-NULL.
853 bool parse_allow_lazy =
854 (info->compile_options() == ScriptCompiler::kConsumeParserCache ||
855 String::cast(script->source())->length() >
856 FLAG_min_preparse_length) &&
857 !Compiler::DebuggerWantsEagerCompilation(info);
858
859 if (!parse_allow_lazy &&
860 (info->compile_options() == ScriptCompiler::kProduceParserCache ||
861 info->compile_options() == ScriptCompiler::kConsumeParserCache)) {
862 // We are going to parse eagerly, but we either 1) have cached data
863 // produced
864 // by lazy parsing or 2) are asked to generate cached data. We cannot
865 // use
866 // the existing data, since it won't contain all the symbols we need for
867 // eager parsing. In addition, it doesn't make sense to produce the data
868 // when parsing eagerly. That data would contain all symbols, but no
869 // functions, so it cannot be used to aid lazy parsing later.
870 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions);
871 }
872 if (!Parser::Parse(info, parse_allow_lazy)) {
873 return Handle<SharedFunctionInfo>::null();
874 }
859 } 875 }
860 876
861 FunctionLiteral* lit = info->function(); 877 FunctionLiteral* lit = info->function();
862 LiveEditFunctionTracker live_edit_tracker(isolate, lit); 878 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
863 879
864 // Measure how long it takes to do the compilation; only take the 880 // Measure how long it takes to do the compilation; only take the
865 // rest of the function into account to avoid overlap with the 881 // rest of the function into account to avoid overlap with the
866 // parsing statistics. 882 // parsing statistics.
867 HistogramTimer* rate = info->is_eval() 883 HistogramTimer* rate = info->is_eval()
868 ? info->isolate()->counters()->compile_eval() 884 ? info->isolate()->counters()->compile_eval()
(...skipping 26 matching lines...) Expand all
895 PROFILE(isolate, CodeCreateEvent( 911 PROFILE(isolate, CodeCreateEvent(
896 log_tag, *info->code(), *result, info, *script_name)); 912 log_tag, *info->code(), *result, info, *script_name));
897 GDBJIT(AddCode(script_name, script, info->code(), info)); 913 GDBJIT(AddCode(script_name, script, info->code(), info));
898 914
899 // Hint to the runtime system used when allocating space for initial 915 // Hint to the runtime system used when allocating space for initial
900 // property space by setting the expected number of properties for 916 // property space by setting the expected number of properties for
901 // the instances of the function. 917 // the instances of the function.
902 SetExpectedNofPropertiesFromEstimate(result, 918 SetExpectedNofPropertiesFromEstimate(result,
903 lit->expected_property_count()); 919 lit->expected_property_count());
904 920
905 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); 921 if (!script.is_null())
922 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
906 923
907 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); 924 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
908 } 925 }
909 926
910 isolate->debug()->OnAfterCompile(script); 927 isolate->debug()->OnAfterCompile(script);
911 928
912 return result; 929 return result;
913 } 930 }
914 931
915 932
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1069 }
1053 1070
1054 if (result.is_null()) isolate->ReportPendingMessages(); 1071 if (result.is_null()) isolate->ReportPendingMessages();
1055 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { 1072 } else if (result->ic_age() != isolate->heap()->global_ic_age()) {
1056 result->ResetForNewContext(isolate->heap()->global_ic_age()); 1073 result->ResetForNewContext(isolate->heap()->global_ic_age());
1057 } 1074 }
1058 return result; 1075 return result;
1059 } 1076 }
1060 1077
1061 1078
1079 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript(
1080 CompilationInfo* info, int source_length) {
1081 Isolate* isolate = info->isolate();
1082 isolate->counters()->total_load_size()->Increment(source_length);
1083 isolate->counters()->total_compile_size()->Increment(source_length);
1084
1085 // TODO(marja): FLAG_use_strict is not honoured and won't be; when the real
1086 // code caching lands, streaming needs to be adapted to use it.
1087
1088 if (FLAG_use_strict) info->SetStrictMode(STRICT);
1089
1090 Handle<SharedFunctionInfo> result = CompileToplevel(info);
1091
1092 if (result.is_null()) isolate->ReportPendingMessages();
1093 return result;
1094 }
1095
1096
1062 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( 1097 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
1063 FunctionLiteral* literal, Handle<Script> script, 1098 FunctionLiteral* literal, Handle<Script> script,
1064 CompilationInfo* outer_info) { 1099 CompilationInfo* outer_info) {
1065 // Precondition: code has been parsed and scopes have been analyzed. 1100 // Precondition: code has been parsed and scopes have been analyzed.
1066 CompilationInfoWithZone info(script); 1101 CompilationInfoWithZone info(script);
1067 info.SetFunction(literal); 1102 info.SetFunction(literal);
1068 info.PrepareForCompilation(literal->scope()); 1103 info.PrepareForCompilation(literal->scope());
1069 info.SetStrictMode(literal->scope()->strict_mode()); 1104 info.SetStrictMode(literal->scope()->strict_mode());
1070 if (outer_info->will_serialize()) info.PrepareForSerializing(); 1105 if (outer_info->will_serialize()) info.PrepareForSerializing();
1071 1106
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 log_tag, *code, *shared, info, script_name, line_num, column_num)); 1386 log_tag, *code, *shared, info, script_name, line_num, column_num));
1352 } 1387 }
1353 1388
1354 GDBJIT(AddCode(Handle<String>(shared->DebugName()), 1389 GDBJIT(AddCode(Handle<String>(shared->DebugName()),
1355 Handle<Script>(info->script()), 1390 Handle<Script>(info->script()),
1356 Handle<Code>(info->code()), 1391 Handle<Code>(info->code()),
1357 info)); 1392 info));
1358 } 1393 }
1359 1394
1360 1395
1396 bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info,
1397 bool allow_lazy_without_ctx) {
1398 return LiveEditFunctionTracker::IsActive(info->isolate()) ||
1399 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
1400 }
1401
1402
1361 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) 1403 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info)
1362 : name_(name), info_(info), zone_(info->isolate()) { 1404 : name_(name), info_(info), zone_(info->isolate()) {
1363 if (FLAG_hydrogen_stats) { 1405 if (FLAG_hydrogen_stats) {
1364 info_zone_start_allocation_size_ = info->zone()->allocation_size(); 1406 info_zone_start_allocation_size_ = info->zone()->allocation_size();
1365 timer_.Start(); 1407 timer_.Start();
1366 } 1408 }
1367 } 1409 }
1368 1410
1369 1411
1370 CompilationPhase::~CompilationPhase() { 1412 CompilationPhase::~CompilationPhase() {
(...skipping 11 matching lines...) Expand all
1382 AllowHandleDereference allow_deref; 1424 AllowHandleDereference allow_deref;
1383 bool tracing_on = info()->IsStub() 1425 bool tracing_on = info()->IsStub()
1384 ? FLAG_trace_hydrogen_stubs 1426 ? FLAG_trace_hydrogen_stubs
1385 : (FLAG_trace_hydrogen && 1427 : (FLAG_trace_hydrogen &&
1386 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); 1428 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
1387 return (tracing_on && 1429 return (tracing_on &&
1388 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); 1430 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
1389 } 1431 }
1390 1432
1391 } } // namespace v8::internal 1433 } } // namespace v8::internal
OLDNEW
« include/v8.h ('K') | « src/compiler.h ('k') | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698