Commit ed689328 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Refactor code generation for global declarations.

(Baseline is http://codereview.chromium.org/9704054/)

R=fschneider@chromium.org
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9722043

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11332 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 43a52c4c
...@@ -806,7 +806,10 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -806,7 +806,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; globals_.Add(variable->name());
globals_.Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
break; break;
case Variable::PARAMETER: case Variable::PARAMETER:
...@@ -861,9 +864,15 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -861,9 +864,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; globals_.Add(variable->name());
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(declaration->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function);
break; break;
}
case Variable::PARAMETER: case Variable::PARAMETER:
case Variable::LOCAL: { case Variable::LOCAL: {
...@@ -911,7 +920,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { ...@@ -911,7 +920,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg): initialize module instance object
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
...@@ -934,7 +943,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { ...@@ -934,7 +943,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg)
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
......
...@@ -568,48 +568,17 @@ void FullCodeGenerator::DoTest(const TestContext* context) { ...@@ -568,48 +568,17 @@ void FullCodeGenerator::DoTest(const TestContext* context) {
void FullCodeGenerator::VisitDeclarations( void FullCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) { ZoneList<Declaration*>* declarations) {
int save_global_count = global_count_; ASSERT(globals_.is_empty());
global_count_ = 0;
AstVisitor::VisitDeclarations(declarations); AstVisitor::VisitDeclarations(declarations);
if (!globals_.is_empty()) {
// Batch declare global functions and variables.
if (global_count_ > 0) {
Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
int length = declarations->length();
for (int j = 0, i = 0; i < length; i++) {
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
if (var->IsUnallocated()) {
array->set(j++, *(var->name()));
FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
if (fun_decl == NULL) {
if (var->binding_needs_init()) {
// In case this binding needs initialization use the hole.
array->set_the_hole(j++);
} else {
array->set_undefined(j++);
}
} else {
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(fun_decl->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) {
SetStackOverflow();
return;
}
array->set(j++, *function);
}
}
}
// Invoke the platform-dependent code generator to do the actual // Invoke the platform-dependent code generator to do the actual
// declaration the global functions and variables. // declaration the global functions and variables.
Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
DeclareGlobals(array); DeclareGlobals(array);
globals_.Clear();
} }
global_count_ = save_global_count;
} }
......
...@@ -83,7 +83,7 @@ class FullCodeGenerator: public AstVisitor { ...@@ -83,7 +83,7 @@ class FullCodeGenerator: public AstVisitor {
scope_(info->scope()), scope_(info->scope()),
nesting_stack_(NULL), nesting_stack_(NULL),
loop_depth_(0), loop_depth_(0),
global_count_(0), globals_(10),
context_(NULL), context_(NULL),
bailout_entries_(info->HasDeoptimizationSupport() bailout_entries_(info->HasDeoptimizationSupport()
? info->function()->ast_node_count() : 0), ? info->function()->ast_node_count() : 0),
...@@ -778,7 +778,7 @@ class FullCodeGenerator: public AstVisitor { ...@@ -778,7 +778,7 @@ class FullCodeGenerator: public AstVisitor {
Label return_label_; Label return_label_;
NestedStatement* nesting_stack_; NestedStatement* nesting_stack_;
int loop_depth_; int loop_depth_;
int global_count_; ZoneList<Handle<Object> > globals_;
const ExpressionContext* context_; const ExpressionContext* context_;
ZoneList<BailoutEntry> bailout_entries_; ZoneList<BailoutEntry> bailout_entries_;
ZoneList<BailoutEntry> stack_checks_; ZoneList<BailoutEntry> stack_checks_;
......
...@@ -612,6 +612,7 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info, ...@@ -612,6 +612,7 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info,
graph_(NULL), graph_(NULL),
current_block_(NULL), current_block_(NULL),
inlined_count_(0), inlined_count_(0),
globals_(10),
zone_(info->isolate()->zone()), zone_(info->isolate()->zone()),
inline_bailout_(false) { inline_bailout_(false) {
// This is not initialized in the initializer list because the // This is not initialized in the initializer list because the
...@@ -7160,70 +7161,40 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { ...@@ -7160,70 +7161,40 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
int length = declarations->length(); ASSERT(globals_.is_empty());
int save_global_count = global_count_;
global_count_ = 0;
AstVisitor::VisitDeclarations(declarations); AstVisitor::VisitDeclarations(declarations);
if (!globals_.is_empty()) {
// Batch declare global functions and variables.
if (global_count_ > 0) {
Handle<FixedArray> array = Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(2 * global_count_, TENURED); isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
for (int j = 0, i = 0; i < length; i++) { for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
if (var->IsUnallocated()) {
array->set(j++, *(var->name()));
FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
if (fun_decl == NULL) {
if (var->binding_needs_init()) {
// In case this binding needs initialization use the hole.
array->set_the_hole(j++);
} else {
array->set_undefined(j++);
}
} else {
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(fun_decl->fun(), info()->script());
// Check for stack-overflow exception.
if (function.is_null()) {
SetStackOverflow();
return;
}
array->set(j++, *function);
}
}
}
int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
DeclareGlobalsNativeFlag::encode(info()->is_native()) | DeclareGlobalsNativeFlag::encode(info()->is_native()) |
DeclareGlobalsLanguageMode::encode(info()->language_mode()); DeclareGlobalsLanguageMode::encode(info()->language_mode());
HInstruction* result = HInstruction* result = new(zone()) HDeclareGlobals(
new(zone()) HDeclareGlobals(environment()->LookupContext(), environment()->LookupContext(), array, flags);
array,
flags);
AddInstruction(result); AddInstruction(result);
globals_.Clear();
} }
global_count_ = save_global_count;
} }
void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
VariableMode mode = declaration->mode(); VariableMode mode = declaration->mode();
Variable* var = proxy->var(); Variable* variable = proxy->var();
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (var->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; globals_.Add(variable->name());
globals_.Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
return; return;
case Variable::PARAMETER: case Variable::PARAMETER:
case Variable::LOCAL: case Variable::LOCAL:
if (hole_init) { if (hole_init) {
HValue* value = graph()->GetConstantHole(); HValue* value = graph()->GetConstantHole();
environment()->Bind(var, value); environment()->Bind(variable, value);
} }
break; break;
case Variable::CONTEXT: case Variable::CONTEXT:
...@@ -7231,7 +7202,7 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { ...@@ -7231,7 +7202,7 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
HValue* value = graph()->GetConstantHole(); HValue* value = graph()->GetConstantHole();
HValue* context = environment()->LookupContext(); HValue* context = environment()->LookupContext();
HStoreContextSlot* store = new HStoreContextSlot( HStoreContextSlot* store = new HStoreContextSlot(
context, var->index(), HStoreContextSlot::kNoCheck, value); context, variable->index(), HStoreContextSlot::kNoCheck, value);
AddInstruction(store); AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
} }
...@@ -7244,16 +7215,22 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { ...@@ -7244,16 +7215,22 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var(); Variable* variable = proxy->var();
switch (var->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; globals_.Add(variable->name());
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(declaration->fun(), info()->script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function);
return; return;
}
case Variable::PARAMETER: case Variable::PARAMETER:
case Variable::LOCAL: { case Variable::LOCAL: {
CHECK_ALIVE(VisitForValue(declaration->fun())); CHECK_ALIVE(VisitForValue(declaration->fun()));
HValue* value = Pop(); HValue* value = Pop();
environment()->Bind(var, value); environment()->Bind(variable, value);
break; break;
} }
case Variable::CONTEXT: { case Variable::CONTEXT: {
...@@ -7261,7 +7238,7 @@ void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { ...@@ -7261,7 +7238,7 @@ void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
HValue* value = Pop(); HValue* value = Pop();
HValue* context = environment()->LookupContext(); HValue* context = environment()->LookupContext();
HStoreContextSlot* store = new HStoreContextSlot( HStoreContextSlot* store = new HStoreContextSlot(
context, var->index(), HStoreContextSlot::kNoCheck, value); context, variable->index(), HStoreContextSlot::kNoCheck, value);
AddInstruction(store); AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
break; break;
...@@ -7276,9 +7253,10 @@ void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { ...@@ -7276,9 +7253,10 @@ void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var(); Variable* var = proxy->var();
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; // TODO(rossberg)
return; return;
}
case Variable::CONTEXT: { case Variable::CONTEXT: {
// TODO(rossberg) // TODO(rossberg)
break; break;
...@@ -7295,9 +7273,10 @@ void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) { ...@@ -7295,9 +7273,10 @@ void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var(); Variable* var = proxy->var();
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; // TODO(rossberg)
return; return;
}
case Variable::CONTEXT: { case Variable::CONTEXT: {
// TODO(rossberg) // TODO(rossberg)
break; break;
......
...@@ -1162,7 +1162,7 @@ class HGraphBuilder: public AstVisitor { ...@@ -1162,7 +1162,7 @@ class HGraphBuilder: public AstVisitor {
HBasicBlock* current_block_; HBasicBlock* current_block_;
int inlined_count_; int inlined_count_;
int global_count_; ZoneList<Handle<Object> > globals_;
Zone* zone_; Zone* zone_;
......
...@@ -782,7 +782,10 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -782,7 +782,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; globals_.Add(variable->name());
globals_.Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
break; break;
case Variable::PARAMETER: case Variable::PARAMETER:
...@@ -836,9 +839,15 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -836,9 +839,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; globals_.Add(variable->name());
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(declaration->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function);
break; break;
}
case Variable::PARAMETER: case Variable::PARAMETER:
case Variable::LOCAL: { case Variable::LOCAL: {
...@@ -883,7 +892,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { ...@@ -883,7 +892,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg): initialize module instance object
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
...@@ -906,7 +915,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { ...@@ -906,7 +915,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg)
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
......
...@@ -779,7 +779,10 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -779,7 +779,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; globals_.Add(variable->name());
globals_.Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
break; break;
case Variable::PARAMETER: case Variable::PARAMETER:
...@@ -833,9 +836,15 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -833,9 +836,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy(); VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED: {
++global_count_; globals_.Add(variable->name());
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(declaration->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function);
break; break;
}
case Variable::PARAMETER: case Variable::PARAMETER:
case Variable::LOCAL: { case Variable::LOCAL: {
...@@ -881,7 +890,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { ...@@ -881,7 +890,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg): initialize module instance object
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
...@@ -904,7 +913,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { ...@@ -904,7 +913,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var(); Variable* variable = proxy->var();
switch (variable->location()) { switch (variable->location()) {
case Variable::UNALLOCATED: case Variable::UNALLOCATED:
++global_count_; // TODO(rossberg)
break; break;
case Variable::CONTEXT: { case Variable::CONTEXT: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment