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

Side by Side Diff: src/compiler.cc

Issue 2840018: [Isolates] Moved more compilation-related globals (builtins, runtime, &c.)... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: rebase Created 10 years, 6 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
« no previous file with comments | « src/codegen.cc ('k') | src/debug.cc » ('j') | src/runtime.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 155
156 156
157 #ifdef ENABLE_DEBUGGER_SUPPORT 157 #ifdef ENABLE_DEBUGGER_SUPPORT
158 Handle<Code> MakeCodeForLiveEdit(CompilationInfo* info) { 158 Handle<Code> MakeCodeForLiveEdit(CompilationInfo* info) {
159 Handle<Context> context = Handle<Context>::null(); 159 Handle<Context> context = Handle<Context>::null();
160 return MakeCode(context, info); 160 return MakeCode(context, info);
161 } 161 }
162 #endif 162 #endif
163 163
164 164
165 static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global, 165 static Handle<SharedFunctionInfo> MakeFunctionInfo(
166 Isolate* isolate,
167 bool is_global,
166 bool is_eval, 168 bool is_eval,
167 Compiler::ValidationState validate, 169 Compiler::ValidationState validate,
168 Handle<Script> script, 170 Handle<Script> script,
169 Handle<Context> context, 171 Handle<Context> context,
170 v8::Extension* extension, 172 v8::Extension* extension,
171 ScriptDataImpl* pre_data) { 173 ScriptDataImpl* pre_data) {
172 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 174 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
173 175
174 PostponeInterruptsScope postpone; 176 PostponeInterruptsScope postpone;
175 177
176 ASSERT(!i::Isolate::Current()->global_context().is_null()); 178 ASSERT(!isolate->global_context().is_null());
177 script->set_context_data((*i::Isolate::Current()->global_context())->data()); 179 script->set_context_data((*isolate->global_context())->data());
178 180
179 bool is_json = (validate == Compiler::VALIDATE_JSON); 181 bool is_json = (validate == Compiler::VALIDATE_JSON);
180 #ifdef ENABLE_DEBUGGER_SUPPORT 182 #ifdef ENABLE_DEBUGGER_SUPPORT
181 if (is_eval || is_json) { 183 if (is_eval || is_json) {
182 script->set_compilation_type( 184 script->set_compilation_type(
183 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) : 185 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
184 Smi::FromInt(Script::COMPILATION_TYPE_EVAL)); 186 Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
185 // For eval scripts add information on the function from which eval was 187 // For eval scripts add information on the function from which eval was
186 // called. 188 // called.
187 if (is_eval) { 189 if (is_eval) {
188 StackTraceFrameIterator it; 190 StackTraceFrameIterator it;
189 if (!it.done()) { 191 if (!it.done()) {
190 script->set_eval_from_shared( 192 script->set_eval_from_shared(
191 JSFunction::cast(it.frame()->function())->shared()); 193 JSFunction::cast(it.frame()->function())->shared());
192 int offset = static_cast<int>( 194 int offset = static_cast<int>(
193 it.frame()->pc() - it.frame()->code()->instruction_start()); 195 it.frame()->pc() - it.frame()->code()->instruction_start());
194 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); 196 script->set_eval_from_instructions_offset(Smi::FromInt(offset));
195 } 197 }
196 } 198 }
197 } 199 }
198 200
199 // Notify debugger 201 // Notify debugger
200 Isolate::Current()->debugger()->OnBeforeCompile(script); 202 isolate->debugger()->OnBeforeCompile(script);
201 #endif 203 #endif
202 204
203 // Only allow non-global compiles for eval. 205 // Only allow non-global compiles for eval.
204 ASSERT(is_eval || is_global); 206 ASSERT(is_eval || is_global);
205 207
206 // Build AST. 208 // Build AST.
207 FunctionLiteral* lit = 209 FunctionLiteral* lit =
208 MakeAST(is_global, script, extension, pre_data, is_json); 210 MakeAST(is_global, script, extension, pre_data, is_json);
209 211
210 LiveEditFunctionTracker live_edit_tracker(lit); 212 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
211 213
212 // Check for parse errors. 214 // Check for parse errors.
213 if (lit == NULL) { 215 if (lit == NULL) {
214 ASSERT(Isolate::Current()->has_pending_exception()); 216 ASSERT(isolate->has_pending_exception());
215 return Handle<SharedFunctionInfo>::null(); 217 return Handle<SharedFunctionInfo>::null();
216 } 218 }
217 219
218 // Measure how long it takes to do the compilation; only take the 220 // Measure how long it takes to do the compilation; only take the
219 // rest of the function into account to avoid overlap with the 221 // rest of the function into account to avoid overlap with the
220 // parsing statistics. 222 // parsing statistics.
221 HistogramTimer* rate = is_eval 223 HistogramTimer* rate = is_eval
222 ? &Counters::compile_eval 224 ? &Counters::compile_eval
223 : &Counters::compile; 225 : &Counters::compile;
224 HistogramTimerScope timer(rate); 226 HistogramTimerScope timer(rate);
225 227
226 // Compile the code. 228 // Compile the code.
227 CompilationInfo info(lit, script, is_eval); 229 CompilationInfo info(lit, script, is_eval);
228 Handle<Code> code = MakeCode(context, &info); 230 Handle<Code> code = MakeCode(context, &info);
229 231
230 // Check for stack-overflow exceptions. 232 // Check for stack-overflow exceptions.
231 if (code.is_null()) { 233 if (code.is_null()) {
232 Isolate::Current()->StackOverflow(); 234 isolate->StackOverflow();
233 return Handle<SharedFunctionInfo>::null(); 235 return Handle<SharedFunctionInfo>::null();
234 } 236 }
235 237
236 if (script->name()->IsString()) { 238 if (script->name()->IsString()) {
237 PROFILE(CodeCreateEvent( 239 PROFILE(CodeCreateEvent(
238 is_eval ? Logger::EVAL_TAG : 240 is_eval ? Logger::EVAL_TAG :
239 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 241 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
240 *code, String::cast(script->name()))); 242 *code, String::cast(script->name())));
241 OPROFILE(CreateNativeCodeRegion(String::cast(script->name()), 243 OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
242 code->instruction_start(), 244 code->instruction_start(),
(...skipping 17 matching lines...) Expand all
260 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); 262 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
261 Compiler::SetFunctionInfo(result, lit, true, script); 263 Compiler::SetFunctionInfo(result, lit, true, script);
262 264
263 // Hint to the runtime system used when allocating space for initial 265 // Hint to the runtime system used when allocating space for initial
264 // property space by setting the expected number of properties for 266 // property space by setting the expected number of properties for
265 // the instances of the function. 267 // the instances of the function.
266 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count()); 268 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
267 269
268 #ifdef ENABLE_DEBUGGER_SUPPORT 270 #ifdef ENABLE_DEBUGGER_SUPPORT
269 // Notify debugger 271 // Notify debugger
270 Isolate::Current()->debugger()->OnAfterCompile( 272 isolate->debugger()->OnAfterCompile(
271 script, Debugger::NO_AFTER_COMPILE_FLAGS); 273 script, Debugger::NO_AFTER_COMPILE_FLAGS);
272 #endif 274 #endif
273 275
274 live_edit_tracker.RecordFunctionInfo(result, lit); 276 live_edit_tracker.RecordFunctionInfo(result, lit);
275 277
276 return result; 278 return result;
277 } 279 }
278 280
279 281
280 static StaticResource<SafeStringInputBuffer> safe_string_input_buffer;
281
282
283 Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, 282 Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
284 Handle<Object> script_name, 283 Handle<Object> script_name,
285 int line_offset, 284 int line_offset,
286 int column_offset, 285 int column_offset,
287 v8::Extension* extension, 286 v8::Extension* extension,
288 ScriptDataImpl* input_pre_data, 287 ScriptDataImpl* input_pre_data,
289 Handle<Object> script_data, 288 Handle<Object> script_data,
290 NativesFlag natives) { 289 NativesFlag natives) {
290 Isolate* isolate = Isolate::Current();
291 int source_length = source->length(); 291 int source_length = source->length();
292 Counters::total_load_size.Increment(source_length); 292 Counters::total_load_size.Increment(source_length);
293 Counters::total_compile_size.Increment(source_length); 293 Counters::total_compile_size.Increment(source_length);
294 294
295 // The VM is in the COMPILER state until exiting this function. 295 // The VM is in the COMPILER state until exiting this function.
296 VMState state(COMPILER); 296 VMState state(COMPILER);
297 297
298 CompilationCache* compilation_cache = Isolate::Current()->compilation_cache(); 298 CompilationCache* compilation_cache = isolate->compilation_cache();
299 299
300 // Do a lookup in the compilation cache but not for extensions. 300 // Do a lookup in the compilation cache but not for extensions.
301 Handle<SharedFunctionInfo> result; 301 Handle<SharedFunctionInfo> result;
302 if (extension == NULL) { 302 if (extension == NULL) {
303 result = compilation_cache->LookupScript(source, 303 result = compilation_cache->LookupScript(source,
304 script_name, 304 script_name,
305 line_offset, 305 line_offset,
306 column_offset); 306 column_offset);
307 } 307 }
308 308
309 if (result.is_null()) { 309 if (result.is_null()) {
310 // No cache entry found. Do pre-parsing and compile the script. 310 // No cache entry found. Do pre-parsing and compile the script.
311 ScriptDataImpl* pre_data = input_pre_data; 311 ScriptDataImpl* pre_data = input_pre_data;
312 if (pre_data == NULL && source_length >= FLAG_min_preparse_length) { 312 if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
313 Access<SafeStringInputBuffer> buf(&safe_string_input_buffer); 313 Access<SafeStringInputBuffer> buf(
314 isolate->compiler_safe_string_input_buffer());
314 buf->Reset(source.location()); 315 buf->Reset(source.location());
315 pre_data = PreParse(source, buf.value(), extension); 316 pre_data = PreParse(source, buf.value(), extension);
316 } 317 }
317 318
318 // Create a script object describing the script to be compiled. 319 // Create a script object describing the script to be compiled.
319 Handle<Script> script = Factory::NewScript(source); 320 Handle<Script> script = Factory::NewScript(source);
320 if (natives == NATIVES_CODE) { 321 if (natives == NATIVES_CODE) {
321 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 322 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
322 } 323 }
323 if (!script_name.is_null()) { 324 if (!script_name.is_null()) {
324 script->set_name(*script_name); 325 script->set_name(*script_name);
325 script->set_line_offset(Smi::FromInt(line_offset)); 326 script->set_line_offset(Smi::FromInt(line_offset));
326 script->set_column_offset(Smi::FromInt(column_offset)); 327 script->set_column_offset(Smi::FromInt(column_offset));
327 } 328 }
328 329
329 script->set_data(script_data.is_null() ? HEAP->undefined_value() 330 script->set_data(script_data.is_null() ? HEAP->undefined_value()
330 : *script_data); 331 : *script_data);
331 332
332 // Compile the function and add it to the cache. 333 // Compile the function and add it to the cache.
333 result = MakeFunctionInfo(true, 334 result = MakeFunctionInfo(isolate,
335 true,
334 false, 336 false,
335 DONT_VALIDATE_JSON, 337 DONT_VALIDATE_JSON,
336 script, 338 script,
337 Handle<Context>::null(), 339 Handle<Context>::null(),
338 extension, 340 extension,
339 pre_data); 341 pre_data);
340 if (extension == NULL && !result.is_null()) { 342 if (extension == NULL && !result.is_null()) {
341 compilation_cache->PutScript(source, result); 343 compilation_cache->PutScript(source, result);
342 } 344 }
343 345
344 // Get rid of the pre-parsing data (if necessary). 346 // Get rid of the pre-parsing data (if necessary).
345 if (input_pre_data == NULL && pre_data != NULL) { 347 if (input_pre_data == NULL && pre_data != NULL) {
346 delete pre_data; 348 delete pre_data;
347 } 349 }
348 } 350 }
349 351
350 if (result.is_null()) Isolate::Current()->ReportPendingMessages(); 352 if (result.is_null()) isolate->ReportPendingMessages();
351 return result; 353 return result;
352 } 354 }
353 355
354 356
355 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, 357 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
356 Handle<Context> context, 358 Handle<Context> context,
357 bool is_global, 359 bool is_global,
358 ValidationState validate) { 360 ValidationState validate) {
361 Isolate* isolate = Isolate::Current();
359 // Note that if validation is required then no path through this 362 // Note that if validation is required then no path through this
360 // function is allowed to return a value without validating that 363 // function is allowed to return a value without validating that
361 // the input is legal json. 364 // the input is legal json.
362 365
363 int source_length = source->length(); 366 int source_length = source->length();
364 Counters::total_eval_size.Increment(source_length); 367 Counters::total_eval_size.Increment(source_length);
365 Counters::total_compile_size.Increment(source_length); 368 Counters::total_compile_size.Increment(source_length);
366 369
367 // The VM is in the COMPILER state until exiting this function. 370 // The VM is in the COMPILER state until exiting this function.
368 VMState state(COMPILER); 371 VMState state(COMPILER);
369 372
370 CompilationCache* compilation_cache = Isolate::Current()->compilation_cache(); 373 CompilationCache* compilation_cache = isolate->compilation_cache();
371 374
372 // Do a lookup in the compilation cache; if the entry is not there, 375 // Do a lookup in the compilation cache; if the entry is not there,
373 // invoke the compiler and add the result to the cache. If we're 376 // invoke the compiler and add the result to the cache. If we're
374 // evaluating json we bypass the cache since we can't be sure a 377 // evaluating json we bypass the cache since we can't be sure a
375 // potential value in the cache has been validated. 378 // potential value in the cache has been validated.
376 Handle<SharedFunctionInfo> result; 379 Handle<SharedFunctionInfo> result;
377 if (validate == DONT_VALIDATE_JSON) 380 if (validate == DONT_VALIDATE_JSON)
378 result = compilation_cache->LookupEval(source, context, is_global); 381 result = compilation_cache->LookupEval(source, context, is_global);
379 382
380 if (result.is_null()) { 383 if (result.is_null()) {
381 // Create a script object describing the script to be compiled. 384 // Create a script object describing the script to be compiled.
382 Handle<Script> script = Factory::NewScript(source); 385 Handle<Script> script = Factory::NewScript(source);
383 result = MakeFunctionInfo(is_global, 386 result = MakeFunctionInfo(isolate,
387 is_global,
384 true, 388 true,
385 validate, 389 validate,
386 script, 390 script,
387 context, 391 context,
388 NULL, 392 NULL,
389 NULL); 393 NULL);
390 if (!result.is_null() && validate != VALIDATE_JSON) { 394 if (!result.is_null() && validate != VALIDATE_JSON) {
391 // For json it's unlikely that we'll ever see exactly the same 395 // For json it's unlikely that we'll ever see exactly the same
392 // string again so we don't use the compilation cache. 396 // string again so we don't use the compilation cache.
393 compilation_cache->PutEval(source, context, is_global, result); 397 compilation_cache->PutEval(source, context, is_global, result);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 469
466 // Check the function has compiled code. 470 // Check the function has compiled code.
467 ASSERT(shared->is_compiled()); 471 ASSERT(shared->is_compiled());
468 return true; 472 return true;
469 } 473 }
470 474
471 475
472 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 476 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
473 Handle<Script> script, 477 Handle<Script> script,
474 AstVisitor* caller) { 478 AstVisitor* caller) {
475 LiveEditFunctionTracker live_edit_tracker(literal); 479 Isolate* isolate = Isolate::Current();
480 LiveEditFunctionTracker live_edit_tracker(isolate, literal);
476 #ifdef DEBUG 481 #ifdef DEBUG
477 // We should not try to compile the same function literal more than 482 // We should not try to compile the same function literal more than
478 // once. 483 // once.
479 literal->mark_as_compiled(); 484 literal->mark_as_compiled();
480 #endif 485 #endif
481 486
482 // Determine if the function can be lazily compiled. This is 487 // Determine if the function can be lazily compiled. This is
483 // necessary to allow some of our builtin JS files to be lazily 488 // necessary to allow some of our builtin JS files to be lazily
484 // compiled. These builtins cannot be handled lazily by the parser, 489 // compiled. These builtins cannot be handled lazily by the parser,
485 // since we have to know if a function uses the special natives 490 // since we have to know if a function uses the special natives
486 // syntax, which is something the parser records. 491 // syntax, which is something the parser records.
487 bool allow_lazy = literal->AllowsLazyCompilation() && 492 bool allow_lazy = literal->AllowsLazyCompilation() &&
488 !LiveEditFunctionTracker::IsActive(); 493 !LiveEditFunctionTracker::IsActive(isolate);
489 494
490 // Generate code 495 // Generate code
491 Handle<Code> code; 496 Handle<Code> code;
492 if (FLAG_lazy && allow_lazy) { 497 if (FLAG_lazy && allow_lazy) {
493 code = ComputeLazyCompile(literal->num_parameters()); 498 code = ComputeLazyCompile(literal->num_parameters());
494 } else { 499 } else {
495 // The bodies of function literals have not yet been visited by 500 // The bodies of function literals have not yet been visited by
496 // the AST optimizer/analyzer. 501 // the AST optimizer/analyzer.
497 if (!Rewriter::Optimize(literal)) { 502 if (!Rewriter::Optimize(literal)) {
498 return Handle<SharedFunctionInfo>::null(); 503 return Handle<SharedFunctionInfo>::null();
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 644 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
640 *code, *func_name)); 645 *code, *func_name));
641 OPROFILE(CreateNativeCodeRegion(*func_name, 646 OPROFILE(CreateNativeCodeRegion(*func_name,
642 code->instruction_start(), 647 code->instruction_start(),
643 code->instruction_size())); 648 code->instruction_size()));
644 } 649 }
645 } 650 }
646 } 651 }
647 652
648 } } // namespace v8::internal 653 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | src/debug.cc » ('j') | src/runtime.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698