2009-03-31 09:02:40 +00:00
|
|
|
// Copyright 2009 the V8 project authors. All rights reserved.
|
2008-07-03 15:10:15 +00:00
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are
|
|
|
|
// met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright
|
|
|
|
// notice, this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above
|
|
|
|
// copyright notice, this list of conditions and the following
|
|
|
|
// disclaimer in the documentation and/or other materials provided
|
|
|
|
// with the distribution.
|
|
|
|
// * Neither the name of Google Inc. nor the names of its
|
|
|
|
// contributors may be used to endorse or promote products derived
|
|
|
|
// from this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
#include "v8.h"
|
|
|
|
|
|
|
|
#include "bootstrapper.h"
|
|
|
|
#include "codegen-inl.h"
|
2008-09-11 10:51:52 +00:00
|
|
|
#include "compilation-cache.h"
|
2008-07-03 15:10:15 +00:00
|
|
|
#include "compiler.h"
|
|
|
|
#include "debug.h"
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
#include "fast-codegen.h"
|
2009-03-31 09:02:40 +00:00
|
|
|
#include "oprofile-agent.h"
|
2008-07-03 15:10:15 +00:00
|
|
|
#include "rewriter.h"
|
2009-03-31 09:02:40 +00:00
|
|
|
#include "scopes.h"
|
2008-07-03 15:10:15 +00:00
|
|
|
#include "usage-analyzer.h"
|
|
|
|
|
2009-05-25 10:05:56 +00:00
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
2008-07-03 15:10:15 +00:00
|
|
|
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
|
|
|
|
class CodeGenSelector: public AstVisitor {
|
|
|
|
public:
|
|
|
|
enum CodeGenTag { NORMAL, FAST };
|
|
|
|
|
|
|
|
CodeGenSelector() : has_supported_syntax_(true) {}
|
|
|
|
|
|
|
|
CodeGenTag Select(FunctionLiteral* fun);
|
|
|
|
|
|
|
|
private:
|
2009-10-21 09:17:39 +00:00
|
|
|
void VisitDeclarations(ZoneList<Declaration*>* decls);
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
void VisitStatements(ZoneList<Statement*>* stmts);
|
|
|
|
|
|
|
|
// AST node visit functions.
|
|
|
|
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
|
|
|
|
AST_NODE_LIST(DECLARE_VISIT)
|
|
|
|
#undef DECLARE_VISIT
|
|
|
|
|
|
|
|
bool has_supported_syntax_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
static Handle<Code> MakeCode(FunctionLiteral* literal,
|
|
|
|
Handle<Script> script,
|
2009-02-24 13:11:53 +00:00
|
|
|
Handle<Context> context,
|
2008-07-03 15:10:15 +00:00
|
|
|
bool is_eval) {
|
|
|
|
ASSERT(literal != NULL);
|
|
|
|
|
|
|
|
// Rewrite the AST by introducing .result assignments where needed.
|
|
|
|
if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
|
2008-07-16 07:07:30 +00:00
|
|
|
// Signal a stack overflow by returning a null handle. The stack
|
|
|
|
// overflow exception will be thrown by the caller.
|
2008-07-03 15:10:15 +00:00
|
|
|
return Handle<Code>::null();
|
|
|
|
}
|
|
|
|
|
2009-05-14 10:29:48 +00:00
|
|
|
{
|
|
|
|
// Compute top scope and allocate variables. For lazy compilation
|
|
|
|
// the top scope only contains the single lazily compiled function,
|
|
|
|
// so this doesn't re-allocate variables repeatedly.
|
|
|
|
HistogramTimerScope timer(&Counters::variable_allocation);
|
|
|
|
Scope* top = literal->scope();
|
|
|
|
while (top->outer_scope() != NULL) top = top->outer_scope();
|
|
|
|
top->AllocateVariables(context);
|
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (Bootstrapper::IsActive() ?
|
|
|
|
FLAG_print_builtin_scopes :
|
|
|
|
FLAG_print_scopes) {
|
|
|
|
literal->scope()->Print();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-10-28 22:33:00 +00:00
|
|
|
// Optimize the AST.
|
2008-11-05 20:39:41 +00:00
|
|
|
if (!Rewriter::Optimize(literal)) {
|
|
|
|
// Signal a stack overflow by returning a null handle. The stack
|
|
|
|
// overflow exception will be thrown by the caller.
|
|
|
|
return Handle<Code>::null();
|
|
|
|
}
|
2008-10-28 22:33:00 +00:00
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Generate code and return it.
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
if (FLAG_fast_compiler) {
|
|
|
|
CodeGenSelector selector;
|
|
|
|
CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
|
|
|
|
if (code_gen == CodeGenSelector::FAST) {
|
2009-10-21 09:17:39 +00:00
|
|
|
return FastCodeGenerator::MakeCode(literal, script, is_eval);
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
ASSERT(code_gen == CodeGenSelector::NORMAL);
|
|
|
|
}
|
|
|
|
return CodeGenerator::MakeCode(literal, script, is_eval);
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-24 12:45:29 +00:00
|
|
|
static bool IsValidJSON(FunctionLiteral* lit) {
|
2009-08-13 10:25:35 +00:00
|
|
|
if (lit->body()->length() != 1)
|
2009-04-24 12:45:29 +00:00
|
|
|
return false;
|
|
|
|
Statement* stmt = lit->body()->at(0);
|
|
|
|
if (stmt->AsExpressionStatement() == NULL)
|
|
|
|
return false;
|
2009-05-13 12:34:35 +00:00
|
|
|
Expression* expr = stmt->AsExpressionStatement()->expression();
|
2009-04-24 12:45:29 +00:00
|
|
|
return expr->IsValidJSON();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
static Handle<JSFunction> MakeFunction(bool is_global,
|
|
|
|
bool is_eval,
|
2009-08-13 10:25:35 +00:00
|
|
|
Compiler::ValidationState validate,
|
2008-07-03 15:10:15 +00:00
|
|
|
Handle<Script> script,
|
2009-02-24 13:11:53 +00:00
|
|
|
Handle<Context> context,
|
2008-07-03 15:10:15 +00:00
|
|
|
v8::Extension* extension,
|
|
|
|
ScriptDataImpl* pre_data) {
|
2009-05-14 12:18:25 +00:00
|
|
|
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2008-07-25 07:37:58 +00:00
|
|
|
PostponeInterruptsScope postpone;
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2009-05-06 08:52:48 +00:00
|
|
|
ASSERT(!i::Top::global_context().is_null());
|
|
|
|
script->set_context_data((*i::Top::global_context())->data());
|
2009-06-08 10:47:49 +00:00
|
|
|
|
2009-04-20 16:36:13 +00:00
|
|
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
2009-08-13 10:25:35 +00:00
|
|
|
bool is_json = (validate == Compiler::VALIDATE_JSON);
|
2009-06-08 10:47:49 +00:00
|
|
|
if (is_eval || is_json) {
|
|
|
|
script->set_compilation_type(
|
|
|
|
is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
|
|
|
|
Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
|
|
|
|
// For eval scripts add information on the function from which eval was
|
|
|
|
// called.
|
|
|
|
if (is_eval) {
|
|
|
|
JavaScriptFrameIterator it;
|
|
|
|
script->set_eval_from_function(it.frame()->function());
|
|
|
|
int offset = it.frame()->pc() - it.frame()->code()->instruction_start();
|
|
|
|
script->set_eval_from_instructions_offset(Smi::FromInt(offset));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Notify debugger
|
|
|
|
Debugger::OnBeforeCompile(script);
|
2009-04-20 16:36:13 +00:00
|
|
|
#endif
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Only allow non-global compiles for eval.
|
|
|
|
ASSERT(is_eval || is_global);
|
|
|
|
|
|
|
|
// Build AST.
|
|
|
|
FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data);
|
|
|
|
|
2008-07-16 07:07:30 +00:00
|
|
|
// Check for parse errors.
|
|
|
|
if (lit == NULL) {
|
|
|
|
ASSERT(Top::has_pending_exception());
|
|
|
|
return Handle<JSFunction>::null();
|
|
|
|
}
|
|
|
|
|
2009-04-24 12:45:29 +00:00
|
|
|
// When parsing JSON we do an ordinary parse and then afterwards
|
|
|
|
// check the AST to ensure it was well-formed. If not we give a
|
|
|
|
// syntax error.
|
2009-08-13 10:25:35 +00:00
|
|
|
if (validate == Compiler::VALIDATE_JSON && !IsValidJSON(lit)) {
|
2009-04-24 12:45:29 +00:00
|
|
|
HandleScope scope;
|
|
|
|
Handle<JSArray> args = Factory::NewJSArray(1);
|
|
|
|
Handle<Object> source(script->source());
|
|
|
|
SetElement(args, 0, source);
|
|
|
|
Handle<Object> result = Factory::NewSyntaxError("invalid_json", args);
|
|
|
|
Top::Throw(*result, NULL);
|
|
|
|
return Handle<JSFunction>::null();
|
|
|
|
}
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Measure how long it takes to do the compilation; only take the
|
|
|
|
// rest of the function into account to avoid overlap with the
|
|
|
|
// parsing statistics.
|
2009-03-13 16:06:31 +00:00
|
|
|
HistogramTimer* rate = is_eval
|
2008-07-03 15:10:15 +00:00
|
|
|
? &Counters::compile_eval
|
|
|
|
: &Counters::compile;
|
2009-03-13 16:06:31 +00:00
|
|
|
HistogramTimerScope timer(rate);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Compile the code.
|
2009-02-24 13:11:53 +00:00
|
|
|
Handle<Code> code = MakeCode(lit, script, context, is_eval);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2008-07-16 07:07:30 +00:00
|
|
|
// Check for stack-overflow exceptions.
|
2008-07-03 15:10:15 +00:00
|
|
|
if (code.is_null()) {
|
2008-12-05 09:57:36 +00:00
|
|
|
Top::StackOverflow();
|
2008-07-03 15:10:15 +00:00
|
|
|
return Handle<JSFunction>::null();
|
|
|
|
}
|
|
|
|
|
2009-03-05 10:53:08 +00:00
|
|
|
#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
|
2009-02-03 14:44:39 +00:00
|
|
|
// Log the code generation for the script. Check explicit whether logging is
|
|
|
|
// to avoid allocating when not required.
|
2009-06-24 13:09:34 +00:00
|
|
|
if (Logger::is_logging() || OProfileAgent::is_enabled()) {
|
2009-02-03 14:44:39 +00:00
|
|
|
if (script->name()->IsString()) {
|
|
|
|
SmartPointer<char> data =
|
|
|
|
String::cast(script->name())->ToCString(DISALLOW_NULLS);
|
2009-06-08 13:39:48 +00:00
|
|
|
LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
|
|
|
|
*code, *data));
|
2009-06-15 16:33:28 +00:00
|
|
|
OProfileAgent::CreateNativeCodeRegion(*data,
|
|
|
|
code->instruction_start(),
|
|
|
|
code->instruction_size());
|
2009-02-03 14:44:39 +00:00
|
|
|
} else {
|
2009-06-08 13:39:48 +00:00
|
|
|
LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
|
|
|
|
*code, ""));
|
2009-03-05 10:53:08 +00:00
|
|
|
OProfileAgent::CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
|
2009-06-15 16:33:28 +00:00
|
|
|
code->instruction_start(),
|
|
|
|
code->instruction_size());
|
2009-02-03 14:44:39 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
2009-02-03 14:44:39 +00:00
|
|
|
#endif
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Allocate function.
|
|
|
|
Handle<JSFunction> fun =
|
|
|
|
Factory::NewFunctionBoilerplate(lit->name(),
|
|
|
|
lit->materialized_literal_count(),
|
|
|
|
code);
|
|
|
|
|
2009-08-14 11:05:42 +00:00
|
|
|
ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
|
|
|
|
CodeGenerator::SetFunctionInfo(fun, lit, true, script);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Hint to the runtime system used when allocating space for initial
|
|
|
|
// property space by setting the expected number of properties for
|
|
|
|
// the instances of the function.
|
|
|
|
SetExpectedNofPropertiesFromEstimate(fun, lit->expected_property_count());
|
|
|
|
|
2009-04-20 16:36:13 +00:00
|
|
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
2008-07-03 15:10:15 +00:00
|
|
|
// Notify debugger
|
|
|
|
Debugger::OnAfterCompile(script, fun);
|
2009-04-20 16:36:13 +00:00
|
|
|
#endif
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
return fun;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static StaticResource<SafeStringInputBuffer> safe_string_input_buffer;
|
|
|
|
|
|
|
|
|
|
|
|
Handle<JSFunction> Compiler::Compile(Handle<String> source,
|
2008-08-14 13:41:48 +00:00
|
|
|
Handle<Object> script_name,
|
2008-07-03 15:10:15 +00:00
|
|
|
int line_offset, int column_offset,
|
|
|
|
v8::Extension* extension,
|
|
|
|
ScriptDataImpl* input_pre_data) {
|
2008-11-03 10:16:05 +00:00
|
|
|
int source_length = source->length();
|
|
|
|
Counters::total_load_size.Increment(source_length);
|
|
|
|
Counters::total_compile_size.Increment(source_length);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// The VM is in the COMPILER state until exiting this function.
|
|
|
|
VMState state(COMPILER);
|
|
|
|
|
2008-09-11 10:51:52 +00:00
|
|
|
// Do a lookup in the compilation cache but not for extensions.
|
|
|
|
Handle<JSFunction> result;
|
|
|
|
if (extension == NULL) {
|
|
|
|
result = CompilationCache::LookupScript(source,
|
|
|
|
script_name,
|
|
|
|
line_offset,
|
|
|
|
column_offset);
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
2008-09-11 10:51:52 +00:00
|
|
|
if (result.is_null()) {
|
|
|
|
// No cache entry found. Do pre-parsing and compile the script.
|
|
|
|
ScriptDataImpl* pre_data = input_pre_data;
|
2008-11-03 10:16:05 +00:00
|
|
|
if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
|
2008-09-11 10:51:52 +00:00
|
|
|
Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
|
|
|
|
buf->Reset(source.location());
|
2009-08-18 07:14:02 +00:00
|
|
|
pre_data = PreParse(source, buf.value(), extension);
|
2008-09-11 10:51:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a script object describing the script to be compiled.
|
|
|
|
Handle<Script> script = Factory::NewScript(source);
|
|
|
|
if (!script_name.is_null()) {
|
|
|
|
script->set_name(*script_name);
|
|
|
|
script->set_line_offset(Smi::FromInt(line_offset));
|
|
|
|
script->set_column_offset(Smi::FromInt(column_offset));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compile the function and add it to the cache.
|
2009-02-24 13:11:53 +00:00
|
|
|
result = MakeFunction(true,
|
2009-04-24 12:45:29 +00:00
|
|
|
false,
|
2009-08-13 10:25:35 +00:00
|
|
|
DONT_VALIDATE_JSON,
|
2009-02-24 13:11:53 +00:00
|
|
|
script,
|
|
|
|
Handle<Context>::null(),
|
|
|
|
extension,
|
|
|
|
pre_data);
|
2008-09-11 10:51:52 +00:00
|
|
|
if (extension == NULL && !result.is_null()) {
|
2009-04-06 18:08:06 +00:00
|
|
|
CompilationCache::PutScript(source, result);
|
2008-09-11 10:51:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get rid of the pre-parsing data (if necessary).
|
|
|
|
if (input_pre_data == NULL && pre_data != NULL) {
|
|
|
|
delete pre_data;
|
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
2008-12-09 13:18:33 +00:00
|
|
|
if (result.is_null()) Top::ReportPendingMessages();
|
2008-07-03 15:10:15 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-25 07:35:45 +00:00
|
|
|
Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
|
2009-02-24 13:11:53 +00:00
|
|
|
Handle<Context> context,
|
2009-04-24 12:45:29 +00:00
|
|
|
bool is_global,
|
2009-08-13 10:25:35 +00:00
|
|
|
ValidationState validate) {
|
|
|
|
// Note that if validation is required then no path through this
|
|
|
|
// function is allowed to return a value without validating that
|
|
|
|
// the input is legal json.
|
|
|
|
|
2008-11-05 10:26:08 +00:00
|
|
|
int source_length = source->length();
|
2008-11-03 10:16:05 +00:00
|
|
|
Counters::total_eval_size.Increment(source_length);
|
|
|
|
Counters::total_compile_size.Increment(source_length);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// The VM is in the COMPILER state until exiting this function.
|
|
|
|
VMState state(COMPILER);
|
2008-09-11 10:51:52 +00:00
|
|
|
|
|
|
|
// Do a lookup in the compilation cache; if the entry is not there,
|
2009-08-13 10:25:35 +00:00
|
|
|
// invoke the compiler and add the result to the cache. If we're
|
|
|
|
// evaluating json we bypass the cache since we can't be sure a
|
|
|
|
// potential value in the cache has been validated.
|
|
|
|
Handle<JSFunction> result;
|
|
|
|
if (validate == DONT_VALIDATE_JSON)
|
|
|
|
result = CompilationCache::LookupEval(source, context, is_global);
|
|
|
|
|
2008-09-11 10:51:52 +00:00
|
|
|
if (result.is_null()) {
|
|
|
|
// Create a script object describing the script to be compiled.
|
|
|
|
Handle<Script> script = Factory::NewScript(source);
|
2009-04-24 12:45:29 +00:00
|
|
|
result = MakeFunction(is_global,
|
|
|
|
true,
|
2009-08-13 10:25:35 +00:00
|
|
|
validate,
|
2009-04-24 12:45:29 +00:00
|
|
|
script,
|
|
|
|
context,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2009-08-13 10:25:35 +00:00
|
|
|
if (!result.is_null() && validate != VALIDATE_JSON) {
|
|
|
|
// For json it's unlikely that we'll ever see exactly the same
|
|
|
|
// string again so we don't use the compilation cache.
|
2009-06-22 11:12:51 +00:00
|
|
|
CompilationCache::PutEval(source, context, is_global, result);
|
2008-09-11 10:51:52 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-05 08:35:52 +00:00
|
|
|
|
2008-09-11 10:51:52 +00:00
|
|
|
return result;
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-17 05:50:52 +00:00
|
|
|
bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
|
|
|
|
int loop_nesting) {
|
2009-05-14 12:18:25 +00:00
|
|
|
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// The VM is in the COMPILER state until exiting this function.
|
|
|
|
VMState state(COMPILER);
|
|
|
|
|
2008-07-25 07:37:58 +00:00
|
|
|
PostponeInterruptsScope postpone;
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Compute name, source code and script data.
|
|
|
|
Handle<String> name(String::cast(shared->name()));
|
|
|
|
Handle<Script> script(Script::cast(shared->script()));
|
|
|
|
|
|
|
|
int start_position = shared->start_position();
|
|
|
|
int end_position = shared->end_position();
|
|
|
|
bool is_expression = shared->is_expression();
|
|
|
|
Counters::total_compile_size.Increment(end_position - start_position);
|
|
|
|
|
|
|
|
// Generate the AST for the lazily compiled function. The AST may be
|
|
|
|
// NULL in case of parser stack overflow.
|
|
|
|
FunctionLiteral* lit = MakeLazyAST(script, name,
|
|
|
|
start_position,
|
|
|
|
end_position,
|
|
|
|
is_expression);
|
|
|
|
|
2008-07-16 07:07:30 +00:00
|
|
|
// Check for parse errors.
|
|
|
|
if (lit == NULL) {
|
|
|
|
ASSERT(Top::has_pending_exception());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-11-17 05:50:52 +00:00
|
|
|
// Update the loop nesting in the function literal.
|
|
|
|
lit->set_loop_nesting(loop_nesting);
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Measure how long it takes to do the lazy compilation; only take
|
|
|
|
// the rest of the function into account to avoid overlap with the
|
|
|
|
// lazy parsing statistics.
|
2009-03-13 16:06:31 +00:00
|
|
|
HistogramTimerScope timer(&Counters::compile_lazy);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2008-07-16 07:07:30 +00:00
|
|
|
// Compile the code.
|
2009-02-24 13:11:53 +00:00
|
|
|
Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2008-12-05 09:57:36 +00:00
|
|
|
// Check for stack-overflow exception.
|
2008-07-03 15:10:15 +00:00
|
|
|
if (code.is_null()) {
|
2008-12-05 09:57:36 +00:00
|
|
|
Top::StackOverflow();
|
2008-07-03 15:10:15 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-03-05 10:53:08 +00:00
|
|
|
#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
|
2009-02-03 14:44:39 +00:00
|
|
|
// Log the code generation. If source information is available include script
|
|
|
|
// name and line number. Check explicit whether logging is enabled as finding
|
|
|
|
// the line number is not for free.
|
2009-06-24 13:09:34 +00:00
|
|
|
if (Logger::is_logging() || OProfileAgent::is_enabled()) {
|
2009-05-20 09:04:13 +00:00
|
|
|
Handle<String> func_name(name->length() > 0 ?
|
|
|
|
*name : shared->inferred_name());
|
2009-02-03 14:44:39 +00:00
|
|
|
if (script->name()->IsString()) {
|
2009-06-22 07:22:09 +00:00
|
|
|
int line_num = GetScriptLineNumber(script, start_position) + 1;
|
2009-06-08 13:39:48 +00:00
|
|
|
LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, *code, *func_name,
|
2009-02-04 12:07:45 +00:00
|
|
|
String::cast(script->name()), line_num));
|
2009-04-14 00:51:59 +00:00
|
|
|
OProfileAgent::CreateNativeCodeRegion(*func_name,
|
2009-03-05 10:53:08 +00:00
|
|
|
String::cast(script->name()),
|
2009-06-15 16:33:28 +00:00
|
|
|
line_num,
|
|
|
|
code->instruction_start(),
|
|
|
|
code->instruction_size());
|
2009-02-03 14:44:39 +00:00
|
|
|
} else {
|
2009-06-08 13:39:48 +00:00
|
|
|
LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, *code, *func_name));
|
2009-06-15 16:33:28 +00:00
|
|
|
OProfileAgent::CreateNativeCodeRegion(*func_name,
|
|
|
|
code->instruction_start(),
|
|
|
|
code->instruction_size());
|
2009-02-03 10:52:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Update the shared function info with the compiled code.
|
|
|
|
shared->set_code(*code);
|
|
|
|
|
|
|
|
// Set the expected number of properties for instances.
|
|
|
|
SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
|
|
|
|
|
2009-08-26 11:03:07 +00:00
|
|
|
// Set the optimication hints after performing lazy compilation, as these are
|
|
|
|
// not set when the function is set up as a lazily compiled function.
|
|
|
|
shared->SetThisPropertyAssignmentsInfo(
|
|
|
|
lit->has_only_this_property_assignments(),
|
|
|
|
lit->has_only_simple_this_property_assignments(),
|
|
|
|
*lit->this_property_assignments());
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Check the function has compiled code.
|
|
|
|
ASSERT(shared->is_compiled());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
|
|
|
|
Scope* scope = fun->scope();
|
|
|
|
|
2009-10-21 09:17:39 +00:00
|
|
|
if (!scope->is_global_scope()) {
|
|
|
|
if (FLAG_trace_bailout) PrintF("Non-global scope\n");
|
|
|
|
return NORMAL;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
ASSERT(scope->num_heap_slots() == 0);
|
|
|
|
ASSERT(scope->arguments() == NULL);
|
|
|
|
|
|
|
|
has_supported_syntax_ = true;
|
2009-10-21 09:17:39 +00:00
|
|
|
VisitDeclarations(fun->scope()->declarations());
|
|
|
|
if (!has_supported_syntax_) return NORMAL;
|
|
|
|
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
VisitStatements(fun->body());
|
|
|
|
return has_supported_syntax_ ? FAST : NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define BAILOUT(reason) \
|
|
|
|
do { \
|
|
|
|
if (FLAG_trace_bailout) { \
|
|
|
|
PrintF("%s\n", reason); \
|
|
|
|
} \
|
|
|
|
has_supported_syntax_ = false; \
|
|
|
|
return; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_BAILOUT \
|
|
|
|
do { \
|
|
|
|
if (!has_supported_syntax_) return; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
|
2009-10-21 09:17:39 +00:00
|
|
|
void CodeGenSelector::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
|
|
|
for (int i = 0; i < decls->length(); i++) {
|
|
|
|
Visit(decls->at(i));
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) {
|
|
|
|
for (int i = 0, len = stmts->length(); i < len; i++) {
|
|
|
|
Visit(stmts->at(i));
|
2009-10-21 09:17:39 +00:00
|
|
|
CHECK_BAILOUT;
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitDeclaration(Declaration* decl) {
|
2009-10-21 09:17:39 +00:00
|
|
|
Variable* var = decl->proxy()->var();
|
|
|
|
if (!var->is_global() || var->mode() == Variable::CONST) {
|
|
|
|
BAILOUT("Non-global declaration");
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitBlock(Block* stmt) {
|
2009-10-21 09:17:39 +00:00
|
|
|
VisitStatements(stmt->statements());
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
|
Added first support for tracking locations of expressions in the
fast-mode code generator.
AST expression nodes are annotated with a location when doing the
initial syntactic check of the AST. In the current implementation,
expression locations are 'temporary' (ie, allocated to the stack) or
'nowhere' (ie, the expression's value is not needed though it must be
evaluated for side effects).
For the assignment '.result = true' on IA32, we had before (with the
true value already on top of the stack):
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
Now:
32 pop [ebp+0xf4]
======== On x64, before:
37 movq rax,[rsp]
41 movq [rbp-0x18],rax
45 pop rax
Now:
37 pop [rbp-0x18]
======== On ARM, before (with the true value in register ip):
36 str ip, [sp, #-4]!
40 ldr ip, [sp, #+0]
44 str ip, [fp, #-12]
48 add sp, sp, #4
Now:
36 str ip, [fp, #-12]
Review URL: http://codereview.chromium.org/267118
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3076 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-15 16:42:22 +00:00
|
|
|
Expression* expr = stmt->expression();
|
|
|
|
Visit(expr);
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
expr->set_location(Location::Nowhere());
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) {
|
2009-10-21 11:56:05 +00:00
|
|
|
// EmptyStatement is supported.
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitIfStatement(IfStatement* stmt) {
|
|
|
|
BAILOUT("IfStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) {
|
|
|
|
BAILOUT("ContinueStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) {
|
|
|
|
BAILOUT("BreakStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
|
|
|
|
Visit(stmt->expression());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) {
|
|
|
|
BAILOUT("WithEnterStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) {
|
|
|
|
BAILOUT("WithExitStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
|
|
BAILOUT("SwitchStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
|
|
|
BAILOUT("DoWhileStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) {
|
|
|
|
BAILOUT("WhileStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitForStatement(ForStatement* stmt) {
|
|
|
|
BAILOUT("ForStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitForInStatement(ForInStatement* stmt) {
|
|
|
|
BAILOUT("ForInStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
|
|
|
BAILOUT("TryCatchStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
|
|
|
BAILOUT("TryFinallyStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
|
|
|
BAILOUT("DebuggerStatement");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) {
|
2009-10-21 09:17:39 +00:00
|
|
|
if (!expr->AllowsLazyCompilation()) {
|
|
|
|
BAILOUT("FunctionLiteral does not allow lazy compilation");
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitFunctionBoilerplateLiteral(
|
|
|
|
FunctionBoilerplateLiteral* expr) {
|
|
|
|
BAILOUT("FunctionBoilerplateLiteral");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitConditional(Conditional* expr) {
|
|
|
|
BAILOUT("Conditional");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitSlot(Slot* expr) {
|
|
|
|
Slot::Type type = expr->type();
|
|
|
|
if (type != Slot::PARAMETER && type != Slot::LOCAL) {
|
|
|
|
BAILOUT("non-parameter/non-local slot reference");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
|
|
|
|
Expression* rewrite = expr->var()->rewrite();
|
2009-10-21 09:38:21 +00:00
|
|
|
if (rewrite != NULL) Visit(rewrite);
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitLiteral(Literal* expr) {
|
2009-10-27 08:48:01 +00:00
|
|
|
// Literals are supported.
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {
|
2009-10-22 09:29:03 +00:00
|
|
|
// RegexpLiterals are supported.
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
|
2009-10-26 13:21:48 +00:00
|
|
|
for (int i = 0; i < expr->properties()->length(); i++) {
|
|
|
|
ObjectLiteral::Property* property = expr->properties()->at(i);
|
|
|
|
Visit(property->key());
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
Visit(property->value());
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) {
|
2009-10-22 10:07:45 +00:00
|
|
|
ZoneList<Expression*>* subexprs = expr->values();
|
|
|
|
for (int i = 0, len = subexprs->length(); i < len; i++) {
|
|
|
|
Expression* subexpr = subexprs->at(i);
|
|
|
|
if (subexpr->AsLiteral() != NULL) continue;
|
|
|
|
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
|
|
|
|
Visit(subexpr);
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) {
|
|
|
|
BAILOUT("CatchExtensionObject");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitAssignment(Assignment* expr) {
|
|
|
|
// We support plain non-compound assignments to parameters and
|
|
|
|
// non-context (stack-allocated) locals.
|
|
|
|
if (expr->starts_initialization_block()) BAILOUT("initialization block");
|
|
|
|
|
|
|
|
Token::Value op = expr->op();
|
|
|
|
if (op == Token::INIT_CONST) BAILOUT("initialize constant");
|
|
|
|
if (op != Token::ASSIGN && op != Token::INIT_VAR) {
|
|
|
|
BAILOUT("compound assignment");
|
|
|
|
}
|
|
|
|
|
|
|
|
Variable* var = expr->target()->AsVariableProxy()->AsVariable();
|
Added support for assignments to global variables in the toplevel code
generator. We use the normal store IC mechanism with the global
object as the receiver. The following code is generated for 'x=true'
at toplevel.
======== IA32:
27 mov eax,0xf5d06161 ;; object: 0xf5d06161 <true>
32 mov ecx,0xf5d09c35 ;; object: 0xf5d09c35 <String[1]: x>
37 push [esi+0x17]
40 call StoreIC_Initialize (0xf5ce75c0) ;; code: STORE_IC, UNINITIALIZED
45 mov [esp],eax
======== X64:
25 movq rax,0x7f867a7b6199 ;; object: 0x7f867a7b6199 <true>
35 movq rcx,0x7f867a7bae71 ;; object: 0x7f867a7bae71 <String[1]: x>
45 push [rsi+0x2f]
49 call StoreIC_Initialize (0x7f8655929ac0) ;; code: STORE_IC, UNINITIALIZED
54 movq [rsp],rax
======== ARM:
32 e59f0054 ldr r0, [pc, #+84] ;; object: 0xf5b78161 <true>
36 e59f2054 ldr r2, [pc, #+84] ;; object: 0xf5b7bc35 <String[1]: x>
40 e598c017 ldr ip, [r8, #+23]
44 e52dc004 str ip, [sp, #-4]!
48 e1a0e00f mov lr, pc
52 e59ff048 ldr pc, [pc, #+72] ;; debug: statement 0
;; code: STORE_IC, UNINITIALIZED
56 e58d0000 str r0, [sp, #+0]
Review URL: http://codereview.chromium.org/305005
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3095 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-20 13:37:26 +00:00
|
|
|
if (var == NULL) BAILOUT("non-variable assignment");
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
|
Added support for assignments to global variables in the toplevel code
generator. We use the normal store IC mechanism with the global
object as the receiver. The following code is generated for 'x=true'
at toplevel.
======== IA32:
27 mov eax,0xf5d06161 ;; object: 0xf5d06161 <true>
32 mov ecx,0xf5d09c35 ;; object: 0xf5d09c35 <String[1]: x>
37 push [esi+0x17]
40 call StoreIC_Initialize (0xf5ce75c0) ;; code: STORE_IC, UNINITIALIZED
45 mov [esp],eax
======== X64:
25 movq rax,0x7f867a7b6199 ;; object: 0x7f867a7b6199 <true>
35 movq rcx,0x7f867a7bae71 ;; object: 0x7f867a7bae71 <String[1]: x>
45 push [rsi+0x2f]
49 call StoreIC_Initialize (0x7f8655929ac0) ;; code: STORE_IC, UNINITIALIZED
54 movq [rsp],rax
======== ARM:
32 e59f0054 ldr r0, [pc, #+84] ;; object: 0xf5b78161 <true>
36 e59f2054 ldr r2, [pc, #+84] ;; object: 0xf5b7bc35 <String[1]: x>
40 e598c017 ldr ip, [r8, #+23]
44 e52dc004 str ip, [sp, #-4]!
48 e1a0e00f mov lr, pc
52 e59ff048 ldr pc, [pc, #+72] ;; debug: statement 0
;; code: STORE_IC, UNINITIALIZED
56 e58d0000 str r0, [sp, #+0]
Review URL: http://codereview.chromium.org/305005
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3095 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-20 13:37:26 +00:00
|
|
|
if (!var->is_global()) {
|
|
|
|
ASSERT(var->slot() != NULL);
|
|
|
|
Slot::Type type = var->slot()->type();
|
|
|
|
if (type != Slot::PARAMETER && type != Slot::LOCAL) {
|
|
|
|
BAILOUT("non-parameter/non-local slot assignment");
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Visit(expr->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitThrow(Throw* expr) {
|
|
|
|
BAILOUT("Throw");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitProperty(Property* expr) {
|
2009-10-27 16:11:12 +00:00
|
|
|
Visit(expr->obj());
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
Visit(expr->key());
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCall(Call* expr) {
|
2009-10-21 09:17:39 +00:00
|
|
|
Expression* fun = expr->expression();
|
|
|
|
ZoneList<Expression*>* args = expr->arguments();
|
|
|
|
Variable* var = fun->AsVariableProxy()->AsVariable();
|
|
|
|
|
|
|
|
// Check for supported calls
|
|
|
|
if (var != NULL && var->is_possibly_eval()) {
|
|
|
|
BAILOUT("Call to a function named 'eval'");
|
|
|
|
} else if (var != NULL && !var->is_this() && var->is_global()) {
|
|
|
|
// ----------------------------------
|
|
|
|
// JavaScript example: 'foo(1, 2, 3)' // foo is global
|
|
|
|
// ----------------------------------
|
|
|
|
} else {
|
|
|
|
BAILOUT("Call to a non-global function");
|
|
|
|
}
|
|
|
|
// Check all arguments to the call
|
|
|
|
for (int i = 0; i < args->length(); i++) {
|
|
|
|
Visit(args->at(i));
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCallNew(CallNew* expr) {
|
2009-10-27 14:52:55 +00:00
|
|
|
Visit(expr->expression());
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
ZoneList<Expression*>* args = expr->arguments();
|
|
|
|
// Check all arguments to the call
|
|
|
|
for (int i = 0; i < args->length(); i++) {
|
|
|
|
Visit(args->at(i));
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
|
2009-10-21 09:17:39 +00:00
|
|
|
// In case of JS runtime function bail out.
|
|
|
|
if (expr->function() == NULL) BAILOUT("CallRuntime");
|
|
|
|
// Check for inline runtime call
|
|
|
|
if (expr->name()->Get(0) == '_' &&
|
|
|
|
CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
|
|
|
|
BAILOUT("InlineRuntimeCall");
|
|
|
|
}
|
|
|
|
for (int i = 0; i < expr->arguments()->length(); i++) {
|
|
|
|
Visit(expr->arguments()->at(i));
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) {
|
|
|
|
BAILOUT("UnaryOperation");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
|
|
|
|
BAILOUT("CountOperation");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
|
2009-10-23 10:42:14 +00:00
|
|
|
switch (expr->op()) {
|
|
|
|
case Token::OR:
|
|
|
|
Visit(expr->left());
|
|
|
|
CHECK_BAILOUT;
|
|
|
|
Visit(expr->right());
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
BAILOUT("Unsupported binary operation");
|
|
|
|
}
|
Initial infrastructure for fast compilation of top-level code. The
fast code generator is optimized for compilation time and code size.
Currently it is only implemented on IA32. It is potentially triggered
for any code in the global scope (including code eval'd in the global
scope). It performs a syntactic check and chooses to compile in fast
mode if the AST contains only supported constructs and matches some
other constraints.
Initially supported constructs are
* ExpressionStatement,
* ReturnStatement,
* VariableProxy (variable references) to parameters and
stack-allocated locals,
* Assignment with lhs a parameter or stack-allocated local, and
* Literal
This allows compilation of literals at the top level and not much
else.
All intermediate values are allocated to temporaries and the stack is
used for all temporaries. The extra memory traffic is a known issue.
The code generated for 'true' is:
0 push ebp
1 mov ebp,esp
3 push esi
4 push edi
5 push 0xf5cca135 ;; object: 0xf5cca135 <undefined>
10 cmp esp,[0x8277efc]
16 jnc 27 (0xf5cbbb1b)
22 call 0xf5cac960 ;; code: STUB, StackCheck, minor: 0
27 push 0xf5cca161 ;; object: 0xf5cca161 <true>
32 mov eax,[esp]
35 mov [ebp+0xf4],eax
38 pop eax
39 mov eax,[ebp+0xf4]
42 mov esp,ebp ;; js return
44 pop ebp
45 ret 0x4
48 mov eax,0xf5cca135 ;; object: 0xf5cca135 <undefined>
53 mov esp,ebp ;; js return
55 pop ebp
56 ret 0x4
Review URL: http://codereview.chromium.org/273050
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2009-10-14 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
|
|
|
|
BAILOUT("CompareOperation");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CodeGenSelector::VisitThisFunction(ThisFunction* expr) {
|
|
|
|
BAILOUT("ThisFunction");
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef BAILOUT
|
|
|
|
#undef CHECK_BAILOUT
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
} } // namespace v8::internal
|