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

Side by Side Diff: src/compiler.cc

Issue 28027: Speed up access to global variables from eval scopes. Traverse the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 10 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 22 matching lines...) Expand all
33 #include "compiler.h" 33 #include "compiler.h"
34 #include "debug.h" 34 #include "debug.h"
35 #include "scopes.h" 35 #include "scopes.h"
36 #include "rewriter.h" 36 #include "rewriter.h"
37 #include "usage-analyzer.h" 37 #include "usage-analyzer.h"
38 38
39 namespace v8 { namespace internal { 39 namespace v8 { namespace internal {
40 40
41 static Handle<Code> MakeCode(FunctionLiteral* literal, 41 static Handle<Code> MakeCode(FunctionLiteral* literal,
42 Handle<Script> script, 42 Handle<Script> script,
43 Handle<Context> context,
43 bool is_eval) { 44 bool is_eval) {
44 ASSERT(literal != NULL); 45 ASSERT(literal != NULL);
45 46
46 // Rewrite the AST by introducing .result assignments where needed. 47 // Rewrite the AST by introducing .result assignments where needed.
47 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { 48 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
48 // Signal a stack overflow by returning a null handle. The stack 49 // Signal a stack overflow by returning a null handle. The stack
49 // overflow exception will be thrown by the caller. 50 // overflow exception will be thrown by the caller.
50 return Handle<Code>::null(); 51 return Handle<Code>::null();
51 } 52 }
52 53
53 // Compute top scope and allocate variables. For lazy compilation 54 // Compute top scope and allocate variables. For lazy compilation
54 // the top scope only contains the single lazily compiled function, 55 // the top scope only contains the single lazily compiled function,
55 // so this doesn't re-allocate variables repeatedly. 56 // so this doesn't re-allocate variables repeatedly.
56 Scope* top = literal->scope(); 57 Scope* top = literal->scope();
57 while (top->outer_scope() != NULL) top = top->outer_scope(); 58 while (top->outer_scope() != NULL) top = top->outer_scope();
58 top->AllocateVariables(); 59 top->AllocateVariables(context);
59 60
60 #ifdef DEBUG 61 #ifdef DEBUG
61 if (Bootstrapper::IsActive() ? 62 if (Bootstrapper::IsActive() ?
62 FLAG_print_builtin_scopes : 63 FLAG_print_builtin_scopes :
63 FLAG_print_scopes) { 64 FLAG_print_scopes) {
64 literal->scope()->Print(); 65 literal->scope()->Print();
65 } 66 }
66 #endif 67 #endif
67 68
68 // Optimize the AST. 69 // Optimize the AST.
69 if (!Rewriter::Optimize(literal)) { 70 if (!Rewriter::Optimize(literal)) {
70 // Signal a stack overflow by returning a null handle. The stack 71 // Signal a stack overflow by returning a null handle. The stack
71 // overflow exception will be thrown by the caller. 72 // overflow exception will be thrown by the caller.
72 return Handle<Code>::null(); 73 return Handle<Code>::null();
73 } 74 }
74 75
75 // Generate code and return it. 76 // Generate code and return it.
76 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); 77 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
77 return result; 78 return result;
78 } 79 }
79 80
80 81
81 static Handle<JSFunction> MakeFunction(bool is_global, 82 static Handle<JSFunction> MakeFunction(bool is_global,
82 bool is_eval, 83 bool is_eval,
83 Handle<Script> script, 84 Handle<Script> script,
85 Handle<Context> context,
84 v8::Extension* extension, 86 v8::Extension* extension,
85 ScriptDataImpl* pre_data) { 87 ScriptDataImpl* pre_data) {
86 ZoneScope zone_scope(DELETE_ON_EXIT); 88 ZoneScope zone_scope(DELETE_ON_EXIT);
87 89
88 // Make sure we have an initial stack limit. 90 // Make sure we have an initial stack limit.
89 StackGuard guard; 91 StackGuard guard;
90 PostponeInterruptsScope postpone; 92 PostponeInterruptsScope postpone;
91 93
92 // Notify debugger 94 // Notify debugger
93 Debugger::OnBeforeCompile(script); 95 Debugger::OnBeforeCompile(script);
(...skipping 12 matching lines...) Expand all
106 108
107 // Measure how long it takes to do the compilation; only take the 109 // Measure how long it takes to do the compilation; only take the
108 // rest of the function into account to avoid overlap with the 110 // rest of the function into account to avoid overlap with the
109 // parsing statistics. 111 // parsing statistics.
110 StatsRate* rate = is_eval 112 StatsRate* rate = is_eval
111 ? &Counters::compile_eval 113 ? &Counters::compile_eval
112 : &Counters::compile; 114 : &Counters::compile;
113 StatsRateScope timer(rate); 115 StatsRateScope timer(rate);
114 116
115 // Compile the code. 117 // Compile the code.
116 Handle<Code> code = MakeCode(lit, script, is_eval); 118 Handle<Code> code = MakeCode(lit, script, context, is_eval);
117 119
118 // Check for stack-overflow exceptions. 120 // Check for stack-overflow exceptions.
119 if (code.is_null()) { 121 if (code.is_null()) {
120 Top::StackOverflow(); 122 Top::StackOverflow();
121 return Handle<JSFunction>::null(); 123 return Handle<JSFunction>::null();
122 } 124 }
123 125
124 #ifdef ENABLE_LOGGING_AND_PROFILING 126 #ifdef ENABLE_LOGGING_AND_PROFILING
125 // Log the code generation for the script. Check explicit whether logging is 127 // Log the code generation for the script. Check explicit whether logging is
126 // to avoid allocating when not required. 128 // to avoid allocating when not required.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 196
195 // Create a script object describing the script to be compiled. 197 // Create a script object describing the script to be compiled.
196 Handle<Script> script = Factory::NewScript(source); 198 Handle<Script> script = Factory::NewScript(source);
197 if (!script_name.is_null()) { 199 if (!script_name.is_null()) {
198 script->set_name(*script_name); 200 script->set_name(*script_name);
199 script->set_line_offset(Smi::FromInt(line_offset)); 201 script->set_line_offset(Smi::FromInt(line_offset));
200 script->set_column_offset(Smi::FromInt(column_offset)); 202 script->set_column_offset(Smi::FromInt(column_offset));
201 } 203 }
202 204
203 // Compile the function and add it to the cache. 205 // Compile the function and add it to the cache.
204 result = MakeFunction(true, false, script, extension, pre_data); 206 result = MakeFunction(true,
207 false,
208 script,
209 Handle<Context>::null(),
210 extension,
211 pre_data);
205 if (extension == NULL && !result.is_null()) { 212 if (extension == NULL && !result.is_null()) {
206 CompilationCache::PutFunction(source, CompilationCache::SCRIPT, result); 213 CompilationCache::PutFunction(source, CompilationCache::SCRIPT, result);
207 } 214 }
208 215
209 // Get rid of the pre-parsing data (if necessary). 216 // Get rid of the pre-parsing data (if necessary).
210 if (input_pre_data == NULL && pre_data != NULL) { 217 if (input_pre_data == NULL && pre_data != NULL) {
211 delete pre_data; 218 delete pre_data;
212 } 219 }
213 } 220 }
214 221
215 if (result.is_null()) Top::ReportPendingMessages(); 222 if (result.is_null()) Top::ReportPendingMessages();
216 223
217 return result; 224 return result;
218 } 225 }
219 226
220 227
221 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, 228 Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
229 Handle<Context> context,
222 int line_offset, 230 int line_offset,
223 bool is_global) { 231 bool is_global) {
224 int source_length = source->length(); 232 int source_length = source->length();
225 Counters::total_eval_size.Increment(source_length); 233 Counters::total_eval_size.Increment(source_length);
226 Counters::total_compile_size.Increment(source_length); 234 Counters::total_compile_size.Increment(source_length);
227 235
228 // The VM is in the COMPILER state until exiting this function. 236 // The VM is in the COMPILER state until exiting this function.
229 VMState state(COMPILER); 237 VMState state(COMPILER);
230 CompilationCache::Entry entry = is_global 238 CompilationCache::Entry entry = is_global
231 ? CompilationCache::EVAL_GLOBAL 239 ? CompilationCache::EVAL_GLOBAL
232 : CompilationCache::EVAL_CONTEXTUAL; 240 : CompilationCache::EVAL_CONTEXTUAL;
233 241
234 // Do a lookup in the compilation cache; if the entry is not there, 242 // Do a lookup in the compilation cache; if the entry is not there,
235 // invoke the compiler and add the result to the cache. 243 // invoke the compiler and add the result to the cache.
236 Handle<JSFunction> result = CompilationCache::LookupEval(source, entry); 244 Handle<JSFunction> result =
245 CompilationCache::LookupEval(source, context, entry);
237 if (result.is_null()) { 246 if (result.is_null()) {
238 // Create a script object describing the script to be compiled. 247 // Create a script object describing the script to be compiled.
239 Handle<Script> script = Factory::NewScript(source); 248 Handle<Script> script = Factory::NewScript(source);
240 script->set_line_offset(Smi::FromInt(line_offset)); 249 script->set_line_offset(Smi::FromInt(line_offset));
241 result = MakeFunction(is_global, true, script, NULL, NULL); 250 result = MakeFunction(is_global, true, script, context, NULL, NULL);
242 if (!result.is_null()) { 251 if (!result.is_null()) {
243 CompilationCache::PutFunction(source, entry, result); 252 CompilationCache::PutEvalFunction(source, context, entry, result);
244 } 253 }
245 } 254 }
246 255
247 return result; 256 return result;
248 } 257 }
249 258
250 259
251 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, 260 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
252 int loop_nesting) { 261 int loop_nesting) {
253 ZoneScope zone_scope(DELETE_ON_EXIT); 262 ZoneScope zone_scope(DELETE_ON_EXIT);
(...skipping 29 matching lines...) Expand all
283 292
284 // Update the loop nesting in the function literal. 293 // Update the loop nesting in the function literal.
285 lit->set_loop_nesting(loop_nesting); 294 lit->set_loop_nesting(loop_nesting);
286 295
287 // Measure how long it takes to do the lazy compilation; only take 296 // Measure how long it takes to do the lazy compilation; only take
288 // the rest of the function into account to avoid overlap with the 297 // the rest of the function into account to avoid overlap with the
289 // lazy parsing statistics. 298 // lazy parsing statistics.
290 StatsRateScope timer(&Counters::compile_lazy); 299 StatsRateScope timer(&Counters::compile_lazy);
291 300
292 // Compile the code. 301 // Compile the code.
293 Handle<Code> code = MakeCode(lit, script, false); 302 Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false);
294 303
295 // Check for stack-overflow exception. 304 // Check for stack-overflow exception.
296 if (code.is_null()) { 305 if (code.is_null()) {
297 Top::StackOverflow(); 306 Top::StackOverflow();
298 return false; 307 return false;
299 } 308 }
300 309
301 #ifdef ENABLE_LOGGING_AND_PROFILING 310 #ifdef ENABLE_LOGGING_AND_PROFILING
302 // Log the code generation. If source information is available include script 311 // Log the code generation. If source information is available include script
303 // name and line number. Check explicit whether logging is enabled as finding 312 // name and line number. Check explicit whether logging is enabled as finding
(...skipping 18 matching lines...) Expand all
322 // Set the expected number of properties for instances. 331 // Set the expected number of properties for instances.
323 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); 332 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
324 333
325 // Check the function has compiled code. 334 // Check the function has compiled code.
326 ASSERT(shared->is_compiled()); 335 ASSERT(shared->is_compiled());
327 return true; 336 return true;
328 } 337 }
329 338
330 339
331 } } // namespace v8::internal 340 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698