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(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) {
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;
case Variable::PARAMETER:
......@@ -861,9 +864,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
case Variable::UNALLOCATED: {
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;
}
case Variable::PARAMETER:
case Variable::LOCAL: {
......@@ -911,7 +920,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg): initialize module instance object
break;
case Variable::CONTEXT: {
......@@ -934,7 +943,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg)
break;
case Variable::CONTEXT: {
......
......@@ -568,48 +568,17 @@ void FullCodeGenerator::DoTest(const TestContext* context) {
void FullCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) {
int save_global_count = global_count_;
global_count_ = 0;
ASSERT(globals_.is_empty());
AstVisitor::VisitDeclarations(declarations);
// 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);
}
}
}
if (!globals_.is_empty()) {
// Invoke the platform-dependent code generator to do the actual
// 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);
globals_.Clear();
}
global_count_ = save_global_count;
}
......
......@@ -83,7 +83,7 @@ class FullCodeGenerator: public AstVisitor {
scope_(info->scope()),
nesting_stack_(NULL),
loop_depth_(0),
global_count_(0),
globals_(10),
context_(NULL),
bailout_entries_(info->HasDeoptimizationSupport()
? info->function()->ast_node_count() : 0),
......@@ -778,7 +778,7 @@ class FullCodeGenerator: public AstVisitor {
Label return_label_;
NestedStatement* nesting_stack_;
int loop_depth_;
int global_count_;
ZoneList<Handle<Object> > globals_;
const ExpressionContext* context_;
ZoneList<BailoutEntry> bailout_entries_;
ZoneList<BailoutEntry> stack_checks_;
......
......@@ -612,6 +612,7 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info,
graph_(NULL),
current_block_(NULL),
inlined_count_(0),
globals_(10),
zone_(info->isolate()->zone()),
inline_bailout_(false) {
// This is not initialized in the initializer list because the
......@@ -7160,70 +7161,40 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
int length = declarations->length();
int save_global_count = global_count_;
global_count_ = 0;
ASSERT(globals_.is_empty());
AstVisitor::VisitDeclarations(declarations);
// Batch declare global functions and variables.
if (global_count_ > 0) {
if (!globals_.is_empty()) {
Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
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(), info()->script());
// Check for stack-overflow exception.
if (function.is_null()) {
SetStackOverflow();
return;
}
array->set(j++, *function);
}
}
}
isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
DeclareGlobalsNativeFlag::encode(info()->is_native()) |
DeclareGlobalsLanguageMode::encode(info()->language_mode());
HInstruction* result =
new(zone()) HDeclareGlobals(environment()->LookupContext(),
array,
flags);
HInstruction* result = new(zone()) HDeclareGlobals(
environment()->LookupContext(), array, flags);
AddInstruction(result);
globals_.Clear();
}
global_count_ = save_global_count;
}
void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy();
VariableMode mode = declaration->mode();
Variable* var = proxy->var();
Variable* variable = proxy->var();
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (var->location()) {
switch (variable->location()) {
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;
case Variable::PARAMETER:
case Variable::LOCAL:
if (hole_init) {
HValue* value = graph()->GetConstantHole();
environment()->Bind(var, value);
environment()->Bind(variable, value);
}
break;
case Variable::CONTEXT:
......@@ -7231,7 +7202,7 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
HValue* value = graph()->GetConstantHole();
HValue* context = environment()->LookupContext();
HStoreContextSlot* store = new HStoreContextSlot(
context, var->index(), HStoreContextSlot::kNoCheck, value);
context, variable->index(), HStoreContextSlot::kNoCheck, value);
AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
}
......@@ -7244,16 +7215,22 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var();
switch (var->location()) {
case Variable::UNALLOCATED:
++global_count_;
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED: {
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;
}
case Variable::PARAMETER:
case Variable::LOCAL: {
CHECK_ALIVE(VisitForValue(declaration->fun()));
HValue* value = Pop();
environment()->Bind(var, value);
environment()->Bind(variable, value);
break;
}
case Variable::CONTEXT: {
......@@ -7261,7 +7238,7 @@ void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
HValue* value = Pop();
HValue* context = environment()->LookupContext();
HStoreContextSlot* store = new HStoreContextSlot(
context, var->index(), HStoreContextSlot::kNoCheck, value);
context, variable->index(), HStoreContextSlot::kNoCheck, value);
AddInstruction(store);
if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
break;
......@@ -7276,9 +7253,10 @@ void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var();
switch (var->location()) {
case Variable::UNALLOCATED:
++global_count_;
case Variable::UNALLOCATED: {
// TODO(rossberg)
return;
}
case Variable::CONTEXT: {
// TODO(rossberg)
break;
......@@ -7295,9 +7273,10 @@ void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy();
Variable* var = proxy->var();
switch (var->location()) {
case Variable::UNALLOCATED:
++global_count_;
case Variable::UNALLOCATED: {
// TODO(rossberg)
return;
}
case Variable::CONTEXT: {
// TODO(rossberg)
break;
......
......@@ -1162,7 +1162,7 @@ class HGraphBuilder: public AstVisitor {
HBasicBlock* current_block_;
int inlined_count_;
int global_count_;
ZoneList<Handle<Object> > globals_;
Zone* zone_;
......
......@@ -782,7 +782,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) {
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;
case Variable::PARAMETER:
......@@ -836,9 +839,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
case Variable::UNALLOCATED: {
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;
}
case Variable::PARAMETER:
case Variable::LOCAL: {
......@@ -883,7 +892,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg): initialize module instance object
break;
case Variable::CONTEXT: {
......@@ -906,7 +915,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg)
break;
case Variable::CONTEXT: {
......
......@@ -779,7 +779,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) {
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;
case Variable::PARAMETER:
......@@ -833,9 +836,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
case Variable::UNALLOCATED: {
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;
}
case Variable::PARAMETER:
case Variable::LOCAL: {
......@@ -881,7 +890,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg): initialize module instance object
break;
case Variable::CONTEXT: {
......@@ -904,7 +913,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED:
++global_count_;
// TODO(rossberg)
break;
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