Defer allocation of native function literals.

R=dcarney@chromium.org
BUG=

Review URL: https://codereview.chromium.org/25164003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17017 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2013-09-30 14:49:11 +00:00
parent 9674a7b1bd
commit c624141bf3
8 changed files with 52 additions and 59 deletions

View File

@ -1143,7 +1143,7 @@ DONT_OPTIMIZE_NODE(WithStatement)
DONT_OPTIMIZE_NODE(TryCatchStatement) DONT_OPTIMIZE_NODE(TryCatchStatement)
DONT_OPTIMIZE_NODE(TryFinallyStatement) DONT_OPTIMIZE_NODE(TryFinallyStatement)
DONT_OPTIMIZE_NODE(DebuggerStatement) DONT_OPTIMIZE_NODE(DebuggerStatement)
DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral) DONT_OPTIMIZE_NODE(NativeFunctionLiteral)
DONT_SELFOPTIMIZE_NODE(DoWhileStatement) DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
DONT_SELFOPTIMIZE_NODE(WhileStatement) DONT_SELFOPTIMIZE_NODE(WhileStatement)

View File

@ -97,7 +97,7 @@ namespace internal {
#define EXPRESSION_NODE_LIST(V) \ #define EXPRESSION_NODE_LIST(V) \
V(FunctionLiteral) \ V(FunctionLiteral) \
V(SharedFunctionInfoLiteral) \ V(NativeFunctionLiteral) \
V(Conditional) \ V(Conditional) \
V(VariableProxy) \ V(VariableProxy) \
V(Literal) \ V(Literal) \
@ -2380,23 +2380,18 @@ class FunctionLiteral V8_FINAL : public Expression {
}; };
class SharedFunctionInfoLiteral V8_FINAL : public Expression { class NativeFunctionLiteral V8_FINAL : public Expression {
public: public:
DECLARE_NODE_TYPE(SharedFunctionInfoLiteral) DECLARE_NODE_TYPE(NativeFunctionLiteral)
Handle<SharedFunctionInfo> shared_function_info() const { Handle<String> name() const { return name_; }
return shared_function_info_;
}
protected: protected:
SharedFunctionInfoLiteral( NativeFunctionLiteral(Isolate* isolate, Handle<String> name)
Isolate* isolate, : Expression(isolate), name_(name) { }
Handle<SharedFunctionInfo> shared_function_info)
: Expression(isolate),
shared_function_info_(shared_function_info) { }
private: private:
Handle<SharedFunctionInfo> shared_function_info_; Handle<String> name_;
}; };
@ -3237,11 +3232,10 @@ class AstNodeFactory V8_FINAL BASE_EMBEDDED {
return lit; return lit;
} }
SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral( NativeFunctionLiteral* NewNativeFunctionLiteral(Handle<String> name) {
Handle<SharedFunctionInfo> shared_function_info) { NativeFunctionLiteral* lit =
SharedFunctionInfoLiteral* lit = new(zone_) NativeFunctionLiteral(isolate_, name);
new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info); VISIT_AND_RETURN(NativeFunctionLiteral, lit)
VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
} }
ThisFunction* NewThisFunction() { ThisFunction* NewThisFunction() {

View File

@ -197,8 +197,8 @@ void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
} }
void BreakableStatementChecker::VisitSharedFunctionInfoLiteral( void BreakableStatementChecker::VisitNativeFunctionLiteral(
SharedFunctionInfoLiteral* expr) { NativeFunctionLiteral* expr) {
} }
@ -1567,10 +1567,33 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
} }
void FullCodeGenerator::VisitSharedFunctionInfoLiteral( void FullCodeGenerator::VisitNativeFunctionLiteral(
SharedFunctionInfoLiteral* expr) { NativeFunctionLiteral* expr) {
Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); Comment cmnt(masm_, "[ NativeFunctionLiteral");
EmitNewClosure(expr->shared_function_info(), false);
// Compute the function template for the native function.
Handle<String> name = expr->name();
v8::Handle<v8::FunctionTemplate> fun_template =
info_->extension()->GetNativeFunction(v8::Utils::ToLocal(name));
ASSERT(!fun_template.IsEmpty());
// Instantiate the function and create a shared function info from it.
Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
const int literals = fun->NumberOfLiterals();
Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
bool is_generator = false;
Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
code, Handle<ScopeInfo>(fun->shared()->scope_info()));
shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info.
shared->set_function_data(fun->shared()->function_data());
int parameters = fun->shared()->formal_parameter_count();
shared->set_formal_parameter_count(parameters);
EmitNewClosure(shared, false);
} }

View File

@ -3983,12 +3983,12 @@ void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
} }
void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( void HOptimizedGraphBuilder::VisitNativeFunctionLiteral(
SharedFunctionInfoLiteral* expr) { NativeFunctionLiteral* expr) {
ASSERT(!HasStackOverflow()); ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL); ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor()); ASSERT(current_block()->HasPredecessor());
return Bailout(kSharedFunctionInfoLiteral); return Bailout(kNativeFunctionLiteral);
} }

View File

@ -1206,6 +1206,7 @@ class MaybeObject BASE_EMBEDDED {
V(kModuleStatement, "Module statement") \ V(kModuleStatement, "Module statement") \
V(kModuleVariable, "Module variable") \ V(kModuleVariable, "Module variable") \
V(kModuleUrl, "Module url") \ V(kModuleUrl, "Module url") \
V(kNativeFunctionLiteral, "Native function literal") \
V(kNoCasesLeft, "no cases left") \ V(kNoCasesLeft, "no cases left") \
V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \ V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \
"No empty arrays here in EmitFastAsciiArrayJoin") \ "No empty arrays here in EmitFastAsciiArrayJoin") \
@ -1249,7 +1250,6 @@ class MaybeObject BASE_EMBEDDED {
V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \ V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \
V(kRegisterWasClobbered, "register was clobbered") \ V(kRegisterWasClobbered, "register was clobbered") \
V(kScopedBlock, "ScopedBlock") \ V(kScopedBlock, "ScopedBlock") \
V(kSharedFunctionInfoLiteral, "Shared function info literal") \
V(kSmiAdditionOverflow, "Smi addition overflow") \ V(kSmiAdditionOverflow, "Smi addition overflow") \
V(kSmiSubtractionOverflow, "Smi subtraction overflow") \ V(kSmiSubtractionOverflow, "Smi subtraction overflow") \
V(kStackFrameTypesMustMatch, "stack frame types must match") \ V(kStackFrameTypesMustMatch, "stack frame types must match") \

View File

@ -1667,27 +1667,6 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
// because of lazy compilation. // because of lazy compilation.
DeclarationScope(VAR)->ForceEagerCompilation(); DeclarationScope(VAR)->ForceEagerCompilation();
// Compute the function template for the native function.
v8::Handle<v8::FunctionTemplate> fun_template =
extension_->GetNativeFunction(v8::Utils::ToLocal(name));
ASSERT(!fun_template.IsEmpty());
// Instantiate the function and create a shared function info from it.
Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
const int literals = fun->NumberOfLiterals();
Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
bool is_generator = false;
Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
code, Handle<ScopeInfo>(fun->shared()->scope_info()));
shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info.
shared->set_function_data(fun->shared()->function_data());
int parameters = fun->shared()->formal_parameter_count();
shared->set_formal_parameter_count(parameters);
// TODO(1240846): It's weird that native function declarations are // TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas // introduced dynamically when we meet their declarations, whereas
// other functions are set up when entering the surrounding scope. // other functions are set up when entering the surrounding scope.
@ -1695,8 +1674,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
Declaration* declaration = Declaration* declaration =
factory()->NewVariableDeclaration(proxy, VAR, top_scope_); factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
Declare(declaration, true, CHECK_OK); Declare(declaration, true, CHECK_OK);
SharedFunctionInfoLiteral* lit = NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(name);
factory()->NewSharedFunctionInfoLiteral(shared);
return factory()->NewExpressionStatement( return factory()->NewExpressionStatement(
factory()->NewAssignment( factory()->NewAssignment(
Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));

View File

@ -297,10 +297,9 @@ void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
} }
void PrettyPrinter::VisitSharedFunctionInfoLiteral( void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
SharedFunctionInfoLiteral* node) {
Print("("); Print("(");
PrintLiteral(node->shared_function_info(), true); PrintLiteral(node->name(), false);
Print(")"); Print(")");
} }
@ -982,10 +981,9 @@ void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
} }
void AstPrinter::VisitSharedFunctionInfoLiteral( void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
SharedFunctionInfoLiteral* node) { IndentedScope indent(this, "NATIVE FUNC LITERAL");
IndentedScope indent(this, "FUNC LITERAL"); PrintLiteralIndented("NAME", node->name(), false);
PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
} }

View File

@ -305,7 +305,7 @@ void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
} }
void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) { void AstTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
} }