Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1098)

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 2167763003: [Interpreter] Avoid allocating pairs array in VisitDeclarations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_merge_binary
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/constant-array-builder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 6c51499740581ec24bd49806ee881bdf76d08d6b..3b5b12edfc615a8cd167d8038ef2a64a0a4a2962 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -532,6 +532,53 @@ class BytecodeGenerator::RegisterResultScope final
Register result_register_;
};
+// Used to build a list of global declaration initial value pairs.
+class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
+ public:
+ GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone)
+ : isolate_(isolate),
+ declaration_pairs_(0, zone),
+ constant_pool_entry_(0),
+ has_constant_pool_entry_(false) {}
+
+ void AddDeclaration(FeedbackVectorSlot slot, Handle<Object> initial_value) {
+ DCHECK(!slot.IsInvalid());
+ declaration_pairs_.push_back(handle(Smi::FromInt(slot.ToInt()), isolate_));
+ declaration_pairs_.push_back(initial_value);
+ }
+
+ Handle<FixedArray> AllocateDeclarationPairs() {
+ DCHECK(has_constant_pool_entry_);
+ int array_index = 0;
+ Handle<FixedArray> data = isolate_->factory()->NewFixedArray(
+ static_cast<int>(declaration_pairs_.size()), TENURED);
+ for (Handle<Object> obj : declaration_pairs_) {
+ data->set(array_index++, *obj);
+ }
+ return data;
+ }
+
+ size_t constant_pool_entry() {
+ DCHECK(has_constant_pool_entry_);
+ return constant_pool_entry_;
+ }
+
+ void set_constant_pool_entry(size_t constant_pool_entry) {
+ DCHECK(!empty());
+ DCHECK(!has_constant_pool_entry_);
+ constant_pool_entry_ = constant_pool_entry;
+ has_constant_pool_entry_ = true;
+ }
+
+ bool empty() { return declaration_pairs_.empty(); }
+
+ private:
+ Isolate* isolate_;
+ ZoneVector<Handle<Object>> declaration_pairs_;
+ size_t constant_pool_entry_;
+ bool has_constant_pool_entry_;
+};
+
BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
: isolate_(info->isolate()),
zone_(info->zone()),
@@ -542,7 +589,9 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
info->SourcePositionRecordingMode())),
info_(info),
scope_(info->scope()),
- globals_(0, info->zone()),
+ globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(),
+ info->zone())),
+ global_declarations_(0, info->zone()),
execution_control_(nullptr),
execution_context_(nullptr),
execution_result_(nullptr),
@@ -553,6 +602,20 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
}
Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
+ GenerateBytecode();
+
+ // Build global declaration pair arrays.
+ for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
+ Handle<FixedArray> declarations =
+ globals_builder->AllocateDeclarationPairs();
+ builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
+ declarations);
+ }
+
+ return builder()->ToBytecodeArray();
+}
+
+void BytecodeGenerator::GenerateBytecode() {
// Initialize the incoming context.
ContextScope incoming_context(this, scope(), false);
@@ -572,9 +635,9 @@ Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
VisitNewLocalFunctionContext();
ContextScope local_function_context(this, scope(), false);
VisitBuildLocalActivationContext();
- MakeBytecodeBody();
+ GenerateBytecodeBody();
} else {
- MakeBytecodeBody();
+ GenerateBytecodeBody();
}
// In generator functions, we may not have visited every yield in the AST
@@ -586,10 +649,9 @@ Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
}
builder()->EnsureReturn();
- return builder()->ToBytecodeArray();
}
-void BytecodeGenerator::MakeBytecodeBody() {
+void BytecodeGenerator::GenerateBytecodeBody() {
// Build the arguments object if it is used.
VisitArgumentsObject(scope()->arguments());
@@ -723,9 +785,8 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
case VariableLocation::UNALLOCATED: {
DCHECK(!variable->binding_needs_init());
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
- DCHECK(!slot.IsInvalid());
- globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
- globals()->push_back(isolate()->factory()->undefined_value());
+ globals_builder()->AddDeclaration(
+ slot, isolate()->factory()->undefined_value());
break;
}
case VariableLocation::LOCAL:
@@ -773,9 +834,7 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
- DCHECK(!slot.IsInvalid());
- globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
- globals()->push_back(function);
+ globals_builder()->AddDeclaration(slot, function);
break;
}
case VariableLocation::PARAMETER:
@@ -810,34 +869,35 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
void BytecodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) {
RegisterAllocationScope register_scope(this);
- DCHECK(globals()->empty());
+ DCHECK(globals_builder()->empty());
for (int i = 0; i < declarations->length(); i++) {
RegisterAllocationScope register_scope(this);
Visit(declarations->at(i));
}
- if (globals()->empty()) return;
- int array_index = 0;
- Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
- static_cast<int>(globals()->size()), TENURED);
- for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
+ if (globals_builder()->empty()) return;
+
+ globals_builder()->set_constant_pool_entry(
+ builder()->AllocateConstantPoolEntry());
int encoded_flags = info()->GetDeclareGlobalsFlags();
register_allocator()->PrepareForConsecutiveAllocations(3);
Register pairs = register_allocator()->NextConsecutiveRegister();
- builder()->LoadLiteral(data);
- builder()->StoreAccumulatorInRegister(pairs);
-
Register flags = register_allocator()->NextConsecutiveRegister();
- builder()->LoadLiteral(Smi::FromInt(encoded_flags));
- builder()->StoreAccumulatorInRegister(flags);
- DCHECK(flags.index() == pairs.index() + 1);
-
Register function = register_allocator()->NextConsecutiveRegister();
- builder()->MoveRegister(Register::function_closure(), function);
- builder()->CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3);
- globals()->clear();
+ // Emit code to declare globals.
+ builder()
+ ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
+ .StoreAccumulatorInRegister(pairs)
+ .LoadLiteral(Smi::FromInt(encoded_flags))
+ .StoreAccumulatorInRegister(flags)
+ .MoveRegister(Register::function_closure(), function)
+ .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3);
+
+ // Push and reset globals builder.
+ global_declarations_.push_back(globals_builder());
+ globals_builder_ = new (zone()) GlobalDeclarationsBuilder(isolate(), zone());
}
void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/constant-array-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698