blob: 7b6734a3a05258825295753a06b723bc50931f99 [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"
Andrei Popescu402d9372010-02-26 13:31:12 +000041#include "liveedit.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000042
43namespace v8 {
44namespace internal {
45
Steve Block3ce2e202009-11-05 08:53:23 +000046
Andrei Popescu31002712010-02-23 13:46:05 +000047static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
48 FunctionLiteral* function = info->function();
49 ASSERT(function != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +000050 // Rewrite the AST by introducing .result assignments where needed.
Andrei Popescu31002712010-02-23 13:46:05 +000051 if (!Rewriter::Process(function) || !AnalyzeVariableUsage(function)) {
Steve Blocka7e24c12009-10-30 11:49:00 +000052 // Signal a stack overflow by returning a null handle. The stack
53 // overflow exception will be thrown by the caller.
54 return Handle<Code>::null();
55 }
56
57 {
58 // Compute top scope and allocate variables. For lazy compilation
59 // the top scope only contains the single lazily compiled function,
60 // so this doesn't re-allocate variables repeatedly.
61 HistogramTimerScope timer(&Counters::variable_allocation);
Andrei Popescu31002712010-02-23 13:46:05 +000062 Scope* top = info->scope();
Steve Blocka7e24c12009-10-30 11:49:00 +000063 while (top->outer_scope() != NULL) top = top->outer_scope();
64 top->AllocateVariables(context);
65 }
66
67#ifdef DEBUG
68 if (Bootstrapper::IsActive() ?
69 FLAG_print_builtin_scopes :
70 FLAG_print_scopes) {
Andrei Popescu31002712010-02-23 13:46:05 +000071 info->scope()->Print();
Steve Blocka7e24c12009-10-30 11:49:00 +000072 }
73#endif
74
75 // Optimize the AST.
Andrei Popescu31002712010-02-23 13:46:05 +000076 if (!Rewriter::Optimize(function)) {
Steve Blocka7e24c12009-10-30 11:49:00 +000077 // Signal a stack overflow by returning a null handle. The stack
78 // overflow exception will be thrown by the caller.
79 return Handle<Code>::null();
80 }
81
Leon Clarked91b9f72010-01-27 17:25:45 +000082 // Generate code and return it. Code generator selection is governed by
83 // which backends are enabled and whether the function is considered
84 // run-once code or not:
85 //
86 // --full-compiler enables the dedicated backend for code we expect to be
87 // run once
88 // --fast-compiler enables a speculative optimizing backend (for
89 // non-run-once code)
90 //
91 // The normal choice of backend can be overridden with the flags
92 // --always-full-compiler and --always-fast-compiler, which are mutually
93 // incompatible.
94 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
95
Leon Clarke4515c472010-02-03 11:58:03 +000096 Handle<SharedFunctionInfo> shared = info->shared_info();
Leon Clarked91b9f72010-01-27 17:25:45 +000097 bool is_run_once = (shared.is_null())
Andrei Popescu31002712010-02-23 13:46:05 +000098 ? info->scope()->is_global_scope()
Leon Clarked91b9f72010-01-27 17:25:45 +000099 : (shared->is_toplevel() || shared->try_full_codegen());
100
101 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
102 FullCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000103 checker.Check(function);
Leon Clarked91b9f72010-01-27 17:25:45 +0000104 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000105 return FullCodeGenerator::MakeCode(info);
Steve Block3ce2e202009-11-05 08:53:23 +0000106 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000107 } else if (FLAG_always_fast_compiler ||
108 (FLAG_fast_compiler && !is_run_once)) {
109 FastCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000110 checker.Check(info);
Leon Clarke4515c472010-02-03 11:58:03 +0000111 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000112 return FastCodeGenerator::MakeCode(info);
Leon Clarke4515c472010-02-03 11:58:03 +0000113 }
Steve Block3ce2e202009-11-05 08:53:23 +0000114 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000115
Andrei Popescu31002712010-02-23 13:46:05 +0000116 return CodeGenerator::MakeCode(info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000117}
118
119
120static Handle<JSFunction> MakeFunction(bool is_global,
121 bool is_eval,
122 Compiler::ValidationState validate,
123 Handle<Script> script,
124 Handle<Context> context,
125 v8::Extension* extension,
126 ScriptDataImpl* pre_data) {
127 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
128
129 PostponeInterruptsScope postpone;
130
131 ASSERT(!i::Top::global_context().is_null());
132 script->set_context_data((*i::Top::global_context())->data());
133
Steve Blocka7e24c12009-10-30 11:49:00 +0000134 bool is_json = (validate == Compiler::VALIDATE_JSON);
Leon Clarke4515c472010-02-03 11:58:03 +0000135#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Blocka7e24c12009-10-30 11:49:00 +0000136 if (is_eval || is_json) {
137 script->set_compilation_type(
138 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
139 Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
140 // For eval scripts add information on the function from which eval was
141 // called.
142 if (is_eval) {
Leon Clarke4515c472010-02-03 11:58:03 +0000143 StackTraceFrameIterator it;
144 if (!it.done()) {
145 script->set_eval_from_shared(
146 JSFunction::cast(it.frame()->function())->shared());
147 int offset = static_cast<int>(
148 it.frame()->pc() - it.frame()->code()->instruction_start());
149 script->set_eval_from_instructions_offset(Smi::FromInt(offset));
150 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 }
152 }
153
154 // Notify debugger
155 Debugger::OnBeforeCompile(script);
156#endif
157
158 // Only allow non-global compiles for eval.
159 ASSERT(is_eval || is_global);
160
161 // Build AST.
Leon Clarke4515c472010-02-03 11:58:03 +0000162 FunctionLiteral* lit =
163 MakeAST(is_global, script, extension, pre_data, is_json);
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
165 // Check for parse errors.
166 if (lit == NULL) {
167 ASSERT(Top::has_pending_exception());
168 return Handle<JSFunction>::null();
169 }
170
Steve Blocka7e24c12009-10-30 11:49:00 +0000171 // Measure how long it takes to do the compilation; only take the
172 // rest of the function into account to avoid overlap with the
173 // parsing statistics.
174 HistogramTimer* rate = is_eval
175 ? &Counters::compile_eval
176 : &Counters::compile;
177 HistogramTimerScope timer(rate);
178
179 // Compile the code.
Andrei Popescu31002712010-02-23 13:46:05 +0000180 CompilationInfo info(lit, script, is_eval);
181 Handle<Code> code = MakeCode(context, &info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000182
183 // Check for stack-overflow exceptions.
184 if (code.is_null()) {
185 Top::StackOverflow();
186 return Handle<JSFunction>::null();
187 }
188
189#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
190 // Log the code generation for the script. Check explicit whether logging is
191 // to avoid allocating when not required.
192 if (Logger::is_logging() || OProfileAgent::is_enabled()) {
193 if (script->name()->IsString()) {
194 SmartPointer<char> data =
195 String::cast(script->name())->ToCString(DISALLOW_NULLS);
196 LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
197 *code, *data));
198 OProfileAgent::CreateNativeCodeRegion(*data,
199 code->instruction_start(),
200 code->instruction_size());
201 } else {
202 LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
203 *code, ""));
204 OProfileAgent::CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
205 code->instruction_start(),
206 code->instruction_size());
207 }
208 }
209#endif
210
211 // Allocate function.
212 Handle<JSFunction> fun =
213 Factory::NewFunctionBoilerplate(lit->name(),
214 lit->materialized_literal_count(),
Steve Blocka7e24c12009-10-30 11:49:00 +0000215 code);
216
217 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
Steve Blockd0582a62009-12-15 09:54:21 +0000218 Compiler::SetFunctionInfo(fun, lit, true, script);
Steve Blocka7e24c12009-10-30 11:49:00 +0000219
220 // Hint to the runtime system used when allocating space for initial
221 // property space by setting the expected number of properties for
222 // the instances of the function.
223 SetExpectedNofPropertiesFromEstimate(fun, lit->expected_property_count());
224
225#ifdef ENABLE_DEBUGGER_SUPPORT
226 // Notify debugger
227 Debugger::OnAfterCompile(script, fun);
228#endif
229
230 return fun;
231}
232
233
234static StaticResource<SafeStringInputBuffer> safe_string_input_buffer;
235
236
237Handle<JSFunction> Compiler::Compile(Handle<String> source,
238 Handle<Object> script_name,
239 int line_offset, int column_offset,
240 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000241 ScriptDataImpl* input_pre_data,
Andrei Popescu402d9372010-02-26 13:31:12 +0000242 Handle<Object> script_data,
Andrei Popescu31002712010-02-23 13:46:05 +0000243 NativesFlag natives) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 int source_length = source->length();
245 Counters::total_load_size.Increment(source_length);
246 Counters::total_compile_size.Increment(source_length);
247
248 // The VM is in the COMPILER state until exiting this function.
249 VMState state(COMPILER);
250
251 // Do a lookup in the compilation cache but not for extensions.
252 Handle<JSFunction> result;
253 if (extension == NULL) {
254 result = CompilationCache::LookupScript(source,
255 script_name,
256 line_offset,
257 column_offset);
258 }
259
260 if (result.is_null()) {
261 // No cache entry found. Do pre-parsing and compile the script.
262 ScriptDataImpl* pre_data = input_pre_data;
263 if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
264 Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
265 buf->Reset(source.location());
266 pre_data = PreParse(source, buf.value(), extension);
267 }
268
269 // Create a script object describing the script to be compiled.
270 Handle<Script> script = Factory::NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000271 if (natives == NATIVES_CODE) {
272 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
273 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000274 if (!script_name.is_null()) {
275 script->set_name(*script_name);
276 script->set_line_offset(Smi::FromInt(line_offset));
277 script->set_column_offset(Smi::FromInt(column_offset));
278 }
279
Andrei Popescu402d9372010-02-26 13:31:12 +0000280 script->set_data(script_data.is_null() ? Heap::undefined_value()
281 : *script_data);
282
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 // Compile the function and add it to the cache.
284 result = MakeFunction(true,
285 false,
286 DONT_VALIDATE_JSON,
287 script,
288 Handle<Context>::null(),
289 extension,
290 pre_data);
291 if (extension == NULL && !result.is_null()) {
292 CompilationCache::PutScript(source, result);
293 }
294
295 // Get rid of the pre-parsing data (if necessary).
296 if (input_pre_data == NULL && pre_data != NULL) {
297 delete pre_data;
298 }
299 }
300
301 if (result.is_null()) Top::ReportPendingMessages();
302 return result;
303}
304
305
306Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
307 Handle<Context> context,
308 bool is_global,
309 ValidationState validate) {
310 // Note that if validation is required then no path through this
311 // function is allowed to return a value without validating that
312 // the input is legal json.
313
314 int source_length = source->length();
315 Counters::total_eval_size.Increment(source_length);
316 Counters::total_compile_size.Increment(source_length);
317
318 // The VM is in the COMPILER state until exiting this function.
319 VMState state(COMPILER);
320
321 // Do a lookup in the compilation cache; if the entry is not there,
322 // invoke the compiler and add the result to the cache. If we're
323 // evaluating json we bypass the cache since we can't be sure a
324 // potential value in the cache has been validated.
325 Handle<JSFunction> result;
326 if (validate == DONT_VALIDATE_JSON)
327 result = CompilationCache::LookupEval(source, context, is_global);
328
329 if (result.is_null()) {
330 // Create a script object describing the script to be compiled.
331 Handle<Script> script = Factory::NewScript(source);
332 result = MakeFunction(is_global,
333 true,
334 validate,
335 script,
336 context,
337 NULL,
338 NULL);
339 if (!result.is_null() && validate != VALIDATE_JSON) {
340 // For json it's unlikely that we'll ever see exactly the same
341 // string again so we don't use the compilation cache.
342 CompilationCache::PutEval(source, context, is_global, result);
343 }
344 }
345
346 return result;
347}
348
349
Leon Clarke4515c472010-02-03 11:58:03 +0000350bool Compiler::CompileLazy(CompilationInfo* info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000351 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
352
353 // The VM is in the COMPILER state until exiting this function.
354 VMState state(COMPILER);
355
356 PostponeInterruptsScope postpone;
357
358 // Compute name, source code and script data.
Leon Clarke4515c472010-02-03 11:58:03 +0000359 Handle<SharedFunctionInfo> shared = info->shared_info();
Steve Blocka7e24c12009-10-30 11:49:00 +0000360 Handle<String> name(String::cast(shared->name()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000361
362 int start_position = shared->start_position();
363 int end_position = shared->end_position();
364 bool is_expression = shared->is_expression();
365 Counters::total_compile_size.Increment(end_position - start_position);
366
367 // Generate the AST for the lazily compiled function. The AST may be
368 // NULL in case of parser stack overflow.
Andrei Popescu31002712010-02-23 13:46:05 +0000369 FunctionLiteral* lit = MakeLazyAST(info->script(),
370 name,
Steve Blocka7e24c12009-10-30 11:49:00 +0000371 start_position,
372 end_position,
373 is_expression);
374
375 // Check for parse errors.
376 if (lit == NULL) {
377 ASSERT(Top::has_pending_exception());
378 return false;
379 }
Andrei Popescu31002712010-02-23 13:46:05 +0000380 info->set_function(lit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000381
Steve Blocka7e24c12009-10-30 11:49:00 +0000382 // Measure how long it takes to do the lazy compilation; only take
383 // the rest of the function into account to avoid overlap with the
384 // lazy parsing statistics.
385 HistogramTimerScope timer(&Counters::compile_lazy);
386
387 // Compile the code.
Andrei Popescu31002712010-02-23 13:46:05 +0000388 Handle<Code> code = MakeCode(Handle<Context>::null(), info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000389
390 // Check for stack-overflow exception.
391 if (code.is_null()) {
392 Top::StackOverflow();
393 return false;
394 }
395
396#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
Andrei Popescu31002712010-02-23 13:46:05 +0000397 LogCodeCreateEvent(Logger::LAZY_COMPILE_TAG,
398 name,
399 Handle<String>(shared->inferred_name()),
400 start_position,
401 info->script(),
402 code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000403#endif
404
405 // Update the shared function info with the compiled code.
406 shared->set_code(*code);
407
408 // Set the expected number of properties for instances.
409 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
410
411 // Set the optimication hints after performing lazy compilation, as these are
412 // not set when the function is set up as a lazily compiled function.
413 shared->SetThisPropertyAssignmentsInfo(
Steve Blocka7e24c12009-10-30 11:49:00 +0000414 lit->has_only_simple_this_property_assignments(),
415 *lit->this_property_assignments());
416
417 // Check the function has compiled code.
418 ASSERT(shared->is_compiled());
419 return true;
420}
421
422
Steve Blockd0582a62009-12-15 09:54:21 +0000423Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
424 Handle<Script> script,
425 AstVisitor* caller) {
426#ifdef DEBUG
427 // We should not try to compile the same function literal more than
428 // once.
429 literal->mark_as_compiled();
430#endif
431
432 // Determine if the function can be lazily compiled. This is
433 // necessary to allow some of our builtin JS files to be lazily
434 // compiled. These builtins cannot be handled lazily by the parser,
435 // since we have to know if a function uses the special natives
436 // syntax, which is something the parser records.
Andrei Popescu402d9372010-02-26 13:31:12 +0000437 bool allow_lazy = literal->AllowsLazyCompilation() &&
438 !LiveEditFunctionTracker::IsActive();
Steve Blockd0582a62009-12-15 09:54:21 +0000439
440 // Generate code
441 Handle<Code> code;
442 if (FLAG_lazy && allow_lazy) {
443 code = ComputeLazyCompile(literal->num_parameters());
444 } else {
445 // The bodies of function literals have not yet been visited by
446 // the AST optimizer/analyzer.
447 if (!Rewriter::Optimize(literal)) {
448 return Handle<JSFunction>::null();
449 }
450
Leon Clarked91b9f72010-01-27 17:25:45 +0000451 // Generate code and return it. The way that the compilation mode
452 // is controlled by the command-line flags is described in
453 // the static helper function MakeCode.
Andrei Popescu31002712010-02-23 13:46:05 +0000454 CompilationInfo info(literal, script, false);
Leon Clarke4515c472010-02-03 11:58:03 +0000455
Leon Clarked91b9f72010-01-27 17:25:45 +0000456 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
457 bool is_run_once = literal->try_full_codegen();
Steve Blockd0582a62009-12-15 09:54:21 +0000458 bool is_compiled = false;
Leon Clarked91b9f72010-01-27 17:25:45 +0000459 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
460 FullCodeGenSyntaxChecker checker;
461 checker.Check(literal);
462 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000463 code = FullCodeGenerator::MakeCode(&info);
Steve Blockd0582a62009-12-15 09:54:21 +0000464 is_compiled = true;
465 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000466 } else if (FLAG_always_fast_compiler ||
467 (FLAG_fast_compiler && !is_run_once)) {
Leon Clarke4515c472010-02-03 11:58:03 +0000468 // Since we are not lazily compiling we do not have a receiver to
469 // specialize for.
Leon Clarked91b9f72010-01-27 17:25:45 +0000470 FastCodeGenSyntaxChecker checker;
Andrei Popescu31002712010-02-23 13:46:05 +0000471 checker.Check(&info);
Leon Clarke4515c472010-02-03 11:58:03 +0000472 if (checker.has_supported_syntax()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000473 code = FastCodeGenerator::MakeCode(&info);
Leon Clarke4515c472010-02-03 11:58:03 +0000474 is_compiled = true;
475 }
Steve Blockd0582a62009-12-15 09:54:21 +0000476 }
477
478 if (!is_compiled) {
Leon Clarked91b9f72010-01-27 17:25:45 +0000479 // We fall back to the classic V8 code generator.
Andrei Popescu31002712010-02-23 13:46:05 +0000480 code = CodeGenerator::MakeCode(&info);
Steve Blockd0582a62009-12-15 09:54:21 +0000481 }
482
483 // Check for stack-overflow exception.
484 if (code.is_null()) {
485 caller->SetStackOverflow();
486 return Handle<JSFunction>::null();
487 }
488
489 // Function compilation complete.
Steve Blockd0582a62009-12-15 09:54:21 +0000490
Andrei Popescu31002712010-02-23 13:46:05 +0000491#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
492 LogCodeCreateEvent(Logger::FUNCTION_TAG,
493 literal->name(),
494 literal->inferred_name(),
495 literal->start_position(),
496 script,
497 code);
Steve Blockd0582a62009-12-15 09:54:21 +0000498#endif
499 }
500
501 // Create a boilerplate function.
502 Handle<JSFunction> function =
503 Factory::NewFunctionBoilerplate(literal->name(),
504 literal->materialized_literal_count(),
505 code);
506 SetFunctionInfo(function, literal, false, script);
507
508#ifdef ENABLE_DEBUGGER_SUPPORT
509 // Notify debugger that a new function has been added.
510 Debugger::OnNewFunction(function);
511#endif
512
513 // Set the expected number of properties for instances and return
514 // the resulting function.
515 SetExpectedNofPropertiesFromEstimate(function,
516 literal->expected_property_count());
517 return function;
518}
519
520
521// Sets the function info on a function.
522// The start_position points to the first '(' character after the function name
523// in the full script source. When counting characters in the script source the
524// the first character is number 0 (not 1).
525void Compiler::SetFunctionInfo(Handle<JSFunction> fun,
526 FunctionLiteral* lit,
527 bool is_toplevel,
528 Handle<Script> script) {
529 fun->shared()->set_length(lit->num_parameters());
530 fun->shared()->set_formal_parameter_count(lit->num_parameters());
531 fun->shared()->set_script(*script);
532 fun->shared()->set_function_token_position(lit->function_token_position());
533 fun->shared()->set_start_position(lit->start_position());
534 fun->shared()->set_end_position(lit->end_position());
535 fun->shared()->set_is_expression(lit->is_expression());
536 fun->shared()->set_is_toplevel(is_toplevel);
537 fun->shared()->set_inferred_name(*lit->inferred_name());
538 fun->shared()->SetThisPropertyAssignmentsInfo(
539 lit->has_only_simple_this_property_assignments(),
540 *lit->this_property_assignments());
Leon Clarked91b9f72010-01-27 17:25:45 +0000541 fun->shared()->set_try_full_codegen(lit->try_full_codegen());
Steve Blockd0582a62009-12-15 09:54:21 +0000542}
543
544
Andrei Popescu31002712010-02-23 13:46:05 +0000545#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
546void Compiler::LogCodeCreateEvent(Logger::LogEventsAndTags tag,
547 Handle<String> name,
548 Handle<String> inferred_name,
549 int start_position,
550 Handle<Script> script,
551 Handle<Code> code) {
552 // Log the code generation. If source information is available
553 // include script name and line number. Check explicitly whether
554 // logging is enabled as finding the line number is not free.
555 if (Logger::is_logging() || OProfileAgent::is_enabled()) {
556 Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
557 if (script->name()->IsString()) {
558 int line_num = GetScriptLineNumber(script, start_position) + 1;
559 LOG(CodeCreateEvent(tag, *code, *func_name,
560 String::cast(script->name()), line_num));
561 OProfileAgent::CreateNativeCodeRegion(*func_name,
562 String::cast(script->name()),
563 line_num,
564 code->instruction_start(),
565 code->instruction_size());
566 } else {
567 LOG(CodeCreateEvent(tag, *code, *func_name));
568 OProfileAgent::CreateNativeCodeRegion(*func_name,
569 code->instruction_start(),
570 code->instruction_size());
571 }
572 }
573}
574#endif
575
Steve Blocka7e24c12009-10-30 11:49:00 +0000576} } // namespace v8::internal