OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "bootstrapper.h" | 30 #include "bootstrapper.h" |
31 #include "codegen-inl.h" | 31 #include "codegen-inl.h" |
| 32 #include "compiler.h" |
32 #include "debug.h" | 33 #include "debug.h" |
33 #include "oprofile-agent.h" | 34 #include "oprofile-agent.h" |
34 #include "prettyprinter.h" | 35 #include "prettyprinter.h" |
35 #include "register-allocator-inl.h" | 36 #include "register-allocator-inl.h" |
36 #include "rewriter.h" | 37 #include "rewriter.h" |
37 #include "runtime.h" | 38 #include "runtime.h" |
38 #include "scopeinfo.h" | 39 #include "scopeinfo.h" |
39 #include "stub-cache.h" | 40 #include "stub-cache.h" |
40 | 41 |
41 namespace v8 { | 42 namespace v8 { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 static Vector<const char> kRegexp = CStrVector("regexp"); | 244 static Vector<const char> kRegexp = CStrVector("regexp"); |
244 if (name->IsEqualTo(kRegexp)) | 245 if (name->IsEqualTo(kRegexp)) |
245 return true; | 246 return true; |
246 } | 247 } |
247 return false; | 248 return false; |
248 } | 249 } |
249 | 250 |
250 #endif | 251 #endif |
251 | 252 |
252 | 253 |
253 // Sets the function info on a function. | |
254 // The start_position points to the first '(' character after the function name | |
255 // in the full script source. When counting characters in the script source the | |
256 // the first character is number 0 (not 1). | |
257 void CodeGenerator::SetFunctionInfo(Handle<JSFunction> fun, | |
258 FunctionLiteral* lit, | |
259 bool is_toplevel, | |
260 Handle<Script> script) { | |
261 fun->shared()->set_length(lit->num_parameters()); | |
262 fun->shared()->set_formal_parameter_count(lit->num_parameters()); | |
263 fun->shared()->set_script(*script); | |
264 fun->shared()->set_function_token_position(lit->function_token_position()); | |
265 fun->shared()->set_start_position(lit->start_position()); | |
266 fun->shared()->set_end_position(lit->end_position()); | |
267 fun->shared()->set_is_expression(lit->is_expression()); | |
268 fun->shared()->set_is_toplevel(is_toplevel); | |
269 fun->shared()->set_inferred_name(*lit->inferred_name()); | |
270 fun->shared()->SetThisPropertyAssignmentsInfo( | |
271 lit->has_only_this_property_assignments(), | |
272 lit->has_only_simple_this_property_assignments(), | |
273 *lit->this_property_assignments()); | |
274 fun->shared()->set_try_fast_codegen(lit->try_fast_codegen()); | |
275 } | |
276 | |
277 | |
278 Handle<Code> CodeGenerator::ComputeLazyCompile(int argc) { | |
279 CALL_HEAP_FUNCTION(StubCache::ComputeLazyCompile(argc), Code); | |
280 } | |
281 | |
282 | |
283 Handle<JSFunction> CodeGenerator::BuildBoilerplate(FunctionLiteral* node) { | |
284 #ifdef DEBUG | |
285 // We should not try to compile the same function literal more than | |
286 // once. | |
287 node->mark_as_compiled(); | |
288 #endif | |
289 | |
290 // Determine if the function can be lazily compiled. This is | |
291 // necessary to allow some of our builtin JS files to be lazily | |
292 // compiled. These builtins cannot be handled lazily by the parser, | |
293 // since we have to know if a function uses the special natives | |
294 // syntax, which is something the parser records. | |
295 bool allow_lazy = node->AllowsLazyCompilation(); | |
296 | |
297 // Generate code | |
298 Handle<Code> code; | |
299 if (FLAG_lazy && allow_lazy) { | |
300 code = ComputeLazyCompile(node->num_parameters()); | |
301 } else { | |
302 // The bodies of function literals have not yet been visited by | |
303 // the AST optimizer/analyzer. | |
304 if (!Rewriter::Optimize(node)) { | |
305 return Handle<JSFunction>::null(); | |
306 } | |
307 | |
308 code = MakeCode(node, script_, false); | |
309 | |
310 // Check for stack-overflow exception. | |
311 if (code.is_null()) { | |
312 SetStackOverflow(); | |
313 return Handle<JSFunction>::null(); | |
314 } | |
315 | |
316 // Function compilation complete. | |
317 LOG(CodeCreateEvent(Logger::FUNCTION_TAG, *code, *node->name())); | |
318 | |
319 #ifdef ENABLE_OPROFILE_AGENT | |
320 OProfileAgent::CreateNativeCodeRegion(*node->name(), | |
321 code->instruction_start(), | |
322 code->instruction_size()); | |
323 #endif | |
324 } | |
325 | |
326 // Create a boilerplate function. | |
327 Handle<JSFunction> function = | |
328 Factory::NewFunctionBoilerplate(node->name(), | |
329 node->materialized_literal_count(), | |
330 code); | |
331 CodeGenerator::SetFunctionInfo(function, node, false, script_); | |
332 | |
333 #ifdef ENABLE_DEBUGGER_SUPPORT | |
334 // Notify debugger that a new function has been added. | |
335 Debugger::OnNewFunction(function); | |
336 #endif | |
337 | |
338 // Set the expected number of properties for instances and return | |
339 // the resulting function. | |
340 SetExpectedNofPropertiesFromEstimate(function, | |
341 node->expected_property_count()); | |
342 return function; | |
343 } | |
344 | |
345 | |
346 Handle<Code> CodeGenerator::ComputeCallInitialize( | 254 Handle<Code> CodeGenerator::ComputeCallInitialize( |
347 int argc, | 255 int argc, |
348 InLoopFlag in_loop) { | 256 InLoopFlag in_loop) { |
349 if (in_loop == IN_LOOP) { | 257 if (in_loop == IN_LOOP) { |
350 // Force the creation of the corresponding stub outside loops, | 258 // Force the creation of the corresponding stub outside loops, |
351 // because it may be used when clearing the ICs later - it is | 259 // because it may be used when clearing the ICs later - it is |
352 // possible for a series of IC transitions to lose the in-loop | 260 // possible for a series of IC transitions to lose the in-loop |
353 // information, and the IC clearing code can't generate a stub | 261 // information, and the IC clearing code can't generate a stub |
354 // that it needs so we need to ensure it is generated already. | 262 // that it needs so we need to ensure it is generated already. |
355 ComputeCallInitialize(argc, NOT_IN_LOOP); | 263 ComputeCallInitialize(argc, NOT_IN_LOOP); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 } else { | 300 } else { |
393 array->set(j++, *(var->name())); | 301 array->set(j++, *(var->name())); |
394 if (node->fun() == NULL) { | 302 if (node->fun() == NULL) { |
395 if (var->mode() == Variable::CONST) { | 303 if (var->mode() == Variable::CONST) { |
396 // In case this is const property use the hole. | 304 // In case this is const property use the hole. |
397 array->set_the_hole(j++); | 305 array->set_the_hole(j++); |
398 } else { | 306 } else { |
399 array->set_undefined(j++); | 307 array->set_undefined(j++); |
400 } | 308 } |
401 } else { | 309 } else { |
402 Handle<JSFunction> function = BuildBoilerplate(node->fun()); | 310 Handle<JSFunction> function = |
| 311 Compiler::BuildBoilerplate(node->fun(), script(), this); |
403 // Check for stack-overflow exception. | 312 // Check for stack-overflow exception. |
404 if (HasStackOverflow()) return; | 313 if (HasStackOverflow()) return; |
405 array->set(j++, *function); | 314 array->set(j++, *function); |
406 } | 315 } |
407 } | 316 } |
408 } | 317 } |
409 | 318 |
410 // Invoke the platform-dependent code generator to do the actual | 319 // Invoke the platform-dependent code generator to do the actual |
411 // declaration the global variables and functions. | 320 // declaration the global variables and functions. |
412 DeclareGlobals(array); | 321 DeclareGlobals(array); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 } | 471 } |
563 } | 472 } |
564 | 473 |
565 | 474 |
566 void ApiGetterEntryStub::SetCustomCache(Code* value) { | 475 void ApiGetterEntryStub::SetCustomCache(Code* value) { |
567 info()->set_load_stub_cache(value); | 476 info()->set_load_stub_cache(value); |
568 } | 477 } |
569 | 478 |
570 | 479 |
571 } } // namespace v8::internal | 480 } } // namespace v8::internal |
OLD | NEW |