blob: 6556d3746024c09a359a503745804402a5c24ea1 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
28#include "v8.h"
29
30#include "bootstrapper.h"
31#include "codegen-inl.h"
32#include "compilation-cache.h"
33#include "compiler.h"
34#include "debug.h"
Leon Clarkeeab96aa2010-01-27 16:31:12 +000035#include "fast-codegen.h"
Leon Clarked91b9f72010-01-27 17:25:45 +000036#include "full-codegen.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "oprofile-agent.h"
38#include "rewriter.h"
39#include "scopes.h"
40#include "usage-analyzer.h"
41
42namespace v8 {
43namespace internal {
44
Steve Block3ce2e202009-11-05 08:53:23 +000045
Andrei Popescu31002712010-02-23 13:46:05 +000046static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
47 FunctionLiteral* function = info->function();
48 ASSERT(function != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +000049 // Rewrite the AST by introducing .result assignments where needed.
Andrei Popescu31002712010-02-23 13:46:05 +000050 if (!Rewriter::Process(function) || !AnalyzeVariableUsage(function)) {
Steve Blocka7e24c12009-10-30 11:49:00 +000051 // Signal a stack overflow by returning a null handle. The stack
52 // overflow exception will be thrown by the caller.
53 return Handle<Code>::null();
54 }
55
56 {
57 // Compute top scope and allocate variables. For lazy compilation
58 // the top scope only contains the single lazily compiled function,
59 // so this doesn't re-allocate variables repeatedly.
60 HistogramTimerScope timer(&Counters::variable_allocation);
Andrei Popescu31002712010-02-23 13:46:05 +000061 Scope* top = info->scope();
Steve Blocka7e24c12009-10-30 11:49:00 +000062 while (top->outer_scope() != NULL) top = top->outer_scope();
63 top->AllocateVariables(context);
64 }
65
66#ifdef DEBUG
67 if (Bootstrapper::IsActive() ?
68 FLAG_print_builtin_scopes :
69 FLAG_print_scopes) {
Andrei Popescu31002712010-02-23 13:46:05 +000070 info->scope()->Print();
Steve Blocka7e24c12009-10-30 11:49:00 +000071 }
72#endif
73
74 // Optimize the AST.
Andrei Popescu31002712010-02-23 13:46:05 +000075 if (!Rewriter::Optimize(function)) {
Steve Blocka7e24c12009-10-30 11:49:00 +000076 // Signal a stack overflow by returning a null handle. The stack
77 // overflow exception will be thrown by the caller.
78 return Handle<Code>::null();
79 }
80
Leon Clarked91b9f72010-01-27 17:25:45 +000081 // Generate code and return it. Code generator selection is governed by
82 // which backends are enabled and whether the function is considered
83 // run-once code or not:
84 //
85 // --full-compiler enables the dedicated backend for code we expect to be
86 // run once
87 // --fast-compiler enables a speculative optimizing backend (for
88 // non-run-once code)
89 //
90 // The normal choice of backend can be overridden with the flags
91 // --always-full-compiler and --always-fast-compiler, which are mutually
92 // incompatible.
93 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
94
Leon Clarke4515c472010-02-03 11:58:03 +000095 Handle<SharedFunctionInfo> shared = info->shared_info();
Leon Clarked91b9f72010-01-27 17:25:45 +000096 bool is_run_once = (shared.is_null())
Andrei Popescu31002712010-02-23 13:46:05 +000097 ? info->scope()->is_global_scope()
Leon Clarked91b9f72010-01-27 17:25:45 +000098 : (shared->is_toplevel() || shared->try_full_codegen());
99
100 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
101 FullCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000102 checker.Check(function);
Leon Clarked91b9f72010-01-27 17:25:45 +0000103 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000104 return FullCodeGenerator::MakeCode(info);
Steve Block3ce2e202009-11-05 08:53:23 +0000105 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000106 } else if (FLAG_always_fast_compiler ||
107 (FLAG_fast_compiler && !is_run_once)) {
108 FastCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000109 checker.Check(info);
Leon Clarke4515c472010-02-03 11:58:03 +0000110 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000111 return FastCodeGenerator::MakeCode(info);
Leon Clarke4515c472010-02-03 11:58:03 +0000112 }
Steve Block3ce2e202009-11-05 08:53:23 +0000113 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000114
Andrei Popescu31002712010-02-23 13:46:05 +0000115 return CodeGenerator::MakeCode(info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000116}
117
118
119static Handle<JSFunction> MakeFunction(bool is_global,
120 bool is_eval,
121 Compiler::ValidationState validate,
122 Handle<Script> script,
123 Handle<Context> context,
124 v8::Extension* extension,
125 ScriptDataImpl* pre_data) {
126 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
127
128 PostponeInterruptsScope postpone;
129
130 ASSERT(!i::Top::global_context().is_null());
131 script->set_context_data((*i::Top::global_context())->data());
132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 bool is_json = (validate == Compiler::VALIDATE_JSON);
Leon Clarke4515c472010-02-03 11:58:03 +0000134#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Blocka7e24c12009-10-30 11:49:00 +0000135 if (is_eval || is_json) {
136 script->set_compilation_type(
137 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
138 Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
139 // For eval scripts add information on the function from which eval was
140 // called.
141 if (is_eval) {
Leon Clarke4515c472010-02-03 11:58:03 +0000142 StackTraceFrameIterator it;
143 if (!it.done()) {
144 script->set_eval_from_shared(
145 JSFunction::cast(it.frame()->function())->shared());
146 int offset = static_cast<int>(
147 it.frame()->pc() - it.frame()->code()->instruction_start());
148 script->set_eval_from_instructions_offset(Smi::FromInt(offset));
149 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 }
151 }
152
153 // Notify debugger
154 Debugger::OnBeforeCompile(script);
155#endif
156
157 // Only allow non-global compiles for eval.
158 ASSERT(is_eval || is_global);
159
160 // Build AST.
Leon Clarke4515c472010-02-03 11:58:03 +0000161 FunctionLiteral* lit =
162 MakeAST(is_global, script, extension, pre_data, is_json);
Steve Blocka7e24c12009-10-30 11:49:00 +0000163
164 // Check for parse errors.
165 if (lit == NULL) {
166 ASSERT(Top::has_pending_exception());
167 return Handle<JSFunction>::null();
168 }
169
Steve Blocka7e24c12009-10-30 11:49:00 +0000170 // Measure how long it takes to do the compilation; only take the
171 // rest of the function into account to avoid overlap with the
172 // parsing statistics.
173 HistogramTimer* rate = is_eval
174 ? &Counters::compile_eval
175 : &Counters::compile;
176 HistogramTimerScope timer(rate);
177
178 // Compile the code.
Andrei Popescu31002712010-02-23 13:46:05 +0000179 CompilationInfo info(lit, script, is_eval);
180 Handle<Code> code = MakeCode(context, &info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000181
182 // Check for stack-overflow exceptions.
183 if (code.is_null()) {
184 Top::StackOverflow();
185 return Handle<JSFunction>::null();
186 }
187
188#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
189 // Log the code generation for the script. Check explicit whether logging is
190 // to avoid allocating when not required.
191 if (Logger::is_logging() || OProfileAgent::is_enabled()) {
192 if (script->name()->IsString()) {
193 SmartPointer<char> data =
194 String::cast(script->name())->ToCString(DISALLOW_NULLS);
195 LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
196 *code, *data));
197 OProfileAgent::CreateNativeCodeRegion(*data,
198 code->instruction_start(),
199 code->instruction_size());
200 } else {
201 LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
202 *code, ""));
203 OProfileAgent::CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
204 code->instruction_start(),
205 code->instruction_size());
206 }
207 }
208#endif
209
210 // Allocate function.
211 Handle<JSFunction> fun =
212 Factory::NewFunctionBoilerplate(lit->name(),
213 lit->materialized_literal_count(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000214 code);
215
216 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
Steve Blockd0582a62009-12-15 09:54:21 +0000217 Compiler::SetFunctionInfo(fun, lit, true, script);
Steve Blocka7e24c12009-10-30 11:49:00 +0000218
219 // Hint to the runtime system used when allocating space for initial
220 // property space by setting the expected number of properties for
221 // the instances of the function.
222 SetExpectedNofPropertiesFromEstimate(fun, lit->expected_property_count());
223
224#ifdef ENABLE_DEBUGGER_SUPPORT
225 // Notify debugger
226 Debugger::OnAfterCompile(script, fun);
227#endif
228
229 return fun;
230}
231
232
233static StaticResource<SafeStringInputBuffer> safe_string_input_buffer;
234
235
236Handle<JSFunction> Compiler::Compile(Handle<String> source,
237 Handle<Object> script_name,
238 int line_offset, int column_offset,
239 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000240 ScriptDataImpl* input_pre_data,
241 NativesFlag natives) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 int source_length = source->length();
243 Counters::total_load_size.Increment(source_length);
244 Counters::total_compile_size.Increment(source_length);
245
246 // The VM is in the COMPILER state until exiting this function.
247 VMState state(COMPILER);
248
249 // Do a lookup in the compilation cache but not for extensions.
250 Handle<JSFunction> result;
251 if (extension == NULL) {
252 result = CompilationCache::LookupScript(source,
253 script_name,
254 line_offset,
255 column_offset);
256 }
257
258 if (result.is_null()) {
259 // No cache entry found. Do pre-parsing and compile the script.
260 ScriptDataImpl* pre_data = input_pre_data;
261 if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
262 Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
263 buf->Reset(source.location());
264 pre_data = PreParse(source, buf.value(), extension);
265 }
266
267 // Create a script object describing the script to be compiled.
268 Handle<Script> script = Factory::NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000269 if (natives == NATIVES_CODE) {
270 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
271 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000272 if (!script_name.is_null()) {
273 script->set_name(*script_name);
274 script->set_line_offset(Smi::FromInt(line_offset));
275 script->set_column_offset(Smi::FromInt(column_offset));
276 }
277
278 // Compile the function and add it to the cache.
279 result = MakeFunction(true,
280 false,
281 DONT_VALIDATE_JSON,
282 script,
283 Handle<Context>::null(),
284 extension,
285 pre_data);
286 if (extension == NULL && !result.is_null()) {
287 CompilationCache::PutScript(source, result);
288 }
289
290 // Get rid of the pre-parsing data (if necessary).
291 if (input_pre_data == NULL && pre_data != NULL) {
292 delete pre_data;
293 }
294 }
295
296 if (result.is_null()) Top::ReportPendingMessages();
297 return result;
298}
299
300
301Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
302 Handle<Context> context,
303 bool is_global,
304 ValidationState validate) {
305 // Note that if validation is required then no path through this
306 // function is allowed to return a value without validating that
307 // the input is legal json.
308
309 int source_length = source->length();
310 Counters::total_eval_size.Increment(source_length);
311 Counters::total_compile_size.Increment(source_length);
312
313 // The VM is in the COMPILER state until exiting this function.
314 VMState state(COMPILER);
315
316 // Do a lookup in the compilation cache; if the entry is not there,
317 // invoke the compiler and add the result to the cache. If we're
318 // evaluating json we bypass the cache since we can't be sure a
319 // potential value in the cache has been validated.
320 Handle<JSFunction> result;
321 if (validate == DONT_VALIDATE_JSON)
322 result = CompilationCache::LookupEval(source, context, is_global);
323
324 if (result.is_null()) {
325 // Create a script object describing the script to be compiled.
326 Handle<Script> script = Factory::NewScript(source);
327 result = MakeFunction(is_global,
328 true,
329 validate,
330 script,
331 context,
332 NULL,
333 NULL);
334 if (!result.is_null() && validate != VALIDATE_JSON) {
335 // For json it's unlikely that we'll ever see exactly the same
336 // string again so we don't use the compilation cache.
337 CompilationCache::PutEval(source, context, is_global, result);
338 }
339 }
340
341 return result;
342}
343
344
Leon Clarke4515c472010-02-03 11:58:03 +0000345bool Compiler::CompileLazy(CompilationInfo* info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000346 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
347
348 // The VM is in the COMPILER state until exiting this function.
349 VMState state(COMPILER);
350
351 PostponeInterruptsScope postpone;
352
353 // Compute name, source code and script data.
Leon Clarke4515c472010-02-03 11:58:03 +0000354 Handle<SharedFunctionInfo> shared = info->shared_info();
Steve Blocka7e24c12009-10-30 11:49:00 +0000355 Handle<String> name(String::cast(shared->name()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000356
357 int start_position = shared->start_position();
358 int end_position = shared->end_position();
359 bool is_expression = shared->is_expression();
360 Counters::total_compile_size.Increment(end_position - start_position);
361
362 // Generate the AST for the lazily compiled function. The AST may be
363 // NULL in case of parser stack overflow.
Andrei Popescu31002712010-02-23 13:46:05 +0000364 FunctionLiteral* lit = MakeLazyAST(info->script(),
365 name,
Steve Blocka7e24c12009-10-30 11:49:00 +0000366 start_position,
367 end_position,
368 is_expression);
369
370 // Check for parse errors.
371 if (lit == NULL) {
372 ASSERT(Top::has_pending_exception());
373 return false;
374 }
Andrei Popescu31002712010-02-23 13:46:05 +0000375 info->set_function(lit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000376
Steve Blocka7e24c12009-10-30 11:49:00 +0000377 // Measure how long it takes to do the lazy compilation; only take
378 // the rest of the function into account to avoid overlap with the
379 // lazy parsing statistics.
380 HistogramTimerScope timer(&Counters::compile_lazy);
381
382 // Compile the code.
Andrei Popescu31002712010-02-23 13:46:05 +0000383 Handle<Code> code = MakeCode(Handle<Context>::null(), info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000384
385 // Check for stack-overflow exception.
386 if (code.is_null()) {
387 Top::StackOverflow();
388 return false;
389 }
390
391#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
Andrei Popescu31002712010-02-23 13:46:05 +0000392 LogCodeCreateEvent(Logger::LAZY_COMPILE_TAG,
393 name,
394 Handle<String>(shared->inferred_name()),
395 start_position,
396 info->script(),
397 code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000398#endif
399
400 // Update the shared function info with the compiled code.
401 shared->set_code(*code);
402
403 // Set the expected number of properties for instances.
404 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
405
406 // Set the optimication hints after performing lazy compilation, as these are
407 // not set when the function is set up as a lazily compiled function.
408 shared->SetThisPropertyAssignmentsInfo(
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 lit->has_only_simple_this_property_assignments(),
410 *lit->this_property_assignments());
411
412 // Check the function has compiled code.
413 ASSERT(shared->is_compiled());
414 return true;
415}
416
417
Steve Blockd0582a62009-12-15 09:54:21 +0000418Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
419 Handle<Script> script,
420 AstVisitor* caller) {
421#ifdef DEBUG
422 // We should not try to compile the same function literal more than
423 // once.
424 literal->mark_as_compiled();
425#endif
426
427 // Determine if the function can be lazily compiled. This is
428 // necessary to allow some of our builtin JS files to be lazily
429 // compiled. These builtins cannot be handled lazily by the parser,
430 // since we have to know if a function uses the special natives
431 // syntax, which is something the parser records.
432 bool allow_lazy = literal->AllowsLazyCompilation();
433
434 // Generate code
435 Handle<Code> code;
436 if (FLAG_lazy && allow_lazy) {
437 code = ComputeLazyCompile(literal->num_parameters());
438 } else {
439 // The bodies of function literals have not yet been visited by
440 // the AST optimizer/analyzer.
441 if (!Rewriter::Optimize(literal)) {
442 return Handle<JSFunction>::null();
443 }
444
Leon Clarked91b9f72010-01-27 17:25:45 +0000445 // Generate code and return it. The way that the compilation mode
446 // is controlled by the command-line flags is described in
447 // the static helper function MakeCode.
Andrei Popescu31002712010-02-23 13:46:05 +0000448 CompilationInfo info(literal, script, false);
Leon Clarke4515c472010-02-03 11:58:03 +0000449
Leon Clarked91b9f72010-01-27 17:25:45 +0000450 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
451 bool is_run_once = literal->try_full_codegen();
Steve Blockd0582a62009-12-15 09:54:21 +0000452 bool is_compiled = false;
Leon Clarked91b9f72010-01-27 17:25:45 +0000453 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
454 FullCodeGenSyntaxChecker checker;
455 checker.Check(literal);
456 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000457 code = FullCodeGenerator::MakeCode(&info);
Steve Blockd0582a62009-12-15 09:54:21 +0000458 is_compiled = true;
459 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000460 } else if (FLAG_always_fast_compiler ||
461 (FLAG_fast_compiler && !is_run_once)) {
Leon Clarke4515c472010-02-03 11:58:03 +0000462 // Since we are not lazily compiling we do not have a receiver to
463 // specialize for.
Leon Clarked91b9f72010-01-27 17:25:45 +0000464 FastCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000465 checker.Check(&info);
Leon Clarke4515c472010-02-03 11:58:03 +0000466 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000467 code = FastCodeGenerator::MakeCode(&info);
Leon Clarke4515c472010-02-03 11:58:03 +0000468 is_compiled = true;
469 }
Steve Blockd0582a62009-12-15 09:54:21 +0000470 }
471
472 if (!is_compiled) {
Leon Clarked91b9f72010-01-27 17:25:45 +0000473 // We fall back to the classic V8 code generator.
Andrei Popescu31002712010-02-23 13:46:05 +0000474 code = CodeGenerator::MakeCode(&info);
Steve Blockd0582a62009-12-15 09:54:21 +0000475 }
476
477 // Check for stack-overflow exception.
478 if (code.is_null()) {
479 caller->SetStackOverflow();
480 return Handle<JSFunction>::null();
481 }
482
483 // Function compilation complete.
Steve Blockd0582a62009-12-15 09:54:21 +0000484
Andrei Popescu31002712010-02-23 13:46:05 +0000485#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
486 LogCodeCreateEvent(Logger::FUNCTION_TAG,
487 literal->name(),
488 literal->inferred_name(),
489 literal->start_position(),
490 script,
491 code);
Steve Blockd0582a62009-12-15 09:54:21 +0000492#endif
493 }
494
495 // Create a boilerplate function.
496 Handle<JSFunction> function =
497 Factory::NewFunctionBoilerplate(literal->name(),
498 literal->materialized_literal_count(),
499 code);
500 SetFunctionInfo(function, literal, false, script);
501
502#ifdef ENABLE_DEBUGGER_SUPPORT
503 // Notify debugger that a new function has been added.
504 Debugger::OnNewFunction(function);
505#endif
506
507 // Set the expected number of properties for instances and return
508 // the resulting function.
509 SetExpectedNofPropertiesFromEstimate(function,
510 literal->expected_property_count());
511 return function;
512}
513
514
515// Sets the function info on a function.
516// The start_position points to the first '(' character after the function name
517// in the full script source. When counting characters in the script source the
518// the first character is number 0 (not 1).
519void Compiler::SetFunctionInfo(Handle<JSFunction> fun,
520 FunctionLiteral* lit,
521 bool is_toplevel,
522 Handle<Script> script) {
523 fun->shared()->set_length(lit->num_parameters());
524 fun->shared()->set_formal_parameter_count(lit->num_parameters());
525 fun->shared()->set_script(*script);
526 fun->shared()->set_function_token_position(lit->function_token_position());
527 fun->shared()->set_start_position(lit->start_position());
528 fun->shared()->set_end_position(lit->end_position());
529 fun->shared()->set_is_expression(lit->is_expression());
530 fun->shared()->set_is_toplevel(is_toplevel);
531 fun->shared()->set_inferred_name(*lit->inferred_name());
532 fun->shared()->SetThisPropertyAssignmentsInfo(
533 lit->has_only_simple_this_property_assignments(),
534 *lit->this_property_assignments());
Leon Clarked91b9f72010-01-27 17:25:45 +0000535 fun->shared()->set_try_full_codegen(lit->try_full_codegen());
Steve Blockd0582a62009-12-15 09:54:21 +0000536}
537
538
Andrei Popescu31002712010-02-23 13:46:05 +0000539#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
540void Compiler::LogCodeCreateEvent(Logger::LogEventsAndTags tag,
541 Handle<String> name,
542 Handle<String> inferred_name,
543 int start_position,
544 Handle<Script> script,
545 Handle<Code> code) {
546 // Log the code generation. If source information is available
547 // include script name and line number. Check explicitly whether
548 // logging is enabled as finding the line number is not free.
549 if (Logger::is_logging() || OProfileAgent::is_enabled()) {
550 Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
551 if (script->name()->IsString()) {
552 int line_num = GetScriptLineNumber(script, start_position) + 1;
553 LOG(CodeCreateEvent(tag, *code, *func_name,
554 String::cast(script->name()), line_num));
555 OProfileAgent::CreateNativeCodeRegion(*func_name,
556 String::cast(script->name()),
557 line_num,
558 code->instruction_start(),
559 code->instruction_size());
560 } else {
561 LOG(CodeCreateEvent(tag, *code, *func_name));
562 OProfileAgent::CreateNativeCodeRegion(*func_name,
563 code->instruction_start(),
564 code->instruction_size());
565 }
566 }
567}
568#endif
569
Steve Blocka7e24c12009-10-30 11:49:00 +0000570} } // namespace v8::internal