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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2242193002: [Interpreter] Avoid accessing Isolate from during bytecode generation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@offheap_sourceposition
Patch Set: Address comments Created 4 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/bytecode-flags.h" 10 #include "src/interpreter/bytecode-flags.h"
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 BytecodeLabels* else_labels_; 593 BytecodeLabels* else_labels_;
594 TestFallthrough fallthrough_; 594 TestFallthrough fallthrough_;
595 bool result_consumed_by_test_; 595 bool result_consumed_by_test_;
596 596
597 DISALLOW_COPY_AND_ASSIGN(TestResultScope); 597 DISALLOW_COPY_AND_ASSIGN(TestResultScope);
598 }; 598 };
599 599
600 // Used to build a list of global declaration initial value pairs. 600 // Used to build a list of global declaration initial value pairs.
601 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { 601 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
602 public: 602 public:
603 GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone) 603 explicit GlobalDeclarationsBuilder(Zone* zone)
604 : isolate_(isolate), 604 : declarations_(0, zone),
605 declarations_(0, zone),
606 constant_pool_entry_(0), 605 constant_pool_entry_(0),
607 has_constant_pool_entry_(false) {} 606 has_constant_pool_entry_(false) {}
608 607
609 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) { 608 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) {
610 DCHECK(!slot.IsInvalid()); 609 DCHECK(!slot.IsInvalid());
611 declarations_.push_back(std::make_pair(slot, func)); 610 declarations_.push_back(std::make_pair(slot, func));
612 } 611 }
613 612
614 void AddUndefinedDeclaration(FeedbackVectorSlot slot) { 613 void AddUndefinedDeclaration(FeedbackVectorSlot slot) {
615 DCHECK(!slot.IsInvalid()); 614 DCHECK(!slot.IsInvalid());
616 declarations_.push_back(std::make_pair(slot, nullptr)); 615 declarations_.push_back(std::make_pair(slot, nullptr));
617 } 616 }
618 617
619 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) { 618 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) {
620 DCHECK(has_constant_pool_entry_); 619 DCHECK(has_constant_pool_entry_);
621 int array_index = 0; 620 int array_index = 0;
622 Handle<FixedArray> pairs = isolate_->factory()->NewFixedArray( 621 Handle<FixedArray> pairs = info->isolate()->factory()->NewFixedArray(
623 static_cast<int>(declarations_.size() * 2), TENURED); 622 static_cast<int>(declarations_.size() * 2), TENURED);
624 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration : 623 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration :
625 declarations_) { 624 declarations_) {
626 FunctionLiteral* func = declaration.second; 625 FunctionLiteral* func = declaration.second;
627 Handle<Object> initial_value; 626 Handle<Object> initial_value;
628 if (func == nullptr) { 627 if (func == nullptr) {
629 initial_value = isolate_->factory()->undefined_value(); 628 initial_value = info->isolate()->factory()->undefined_value();
630 } else { 629 } else {
631 initial_value = 630 initial_value =
632 Compiler::GetSharedFunctionInfo(func, info->script(), info); 631 Compiler::GetSharedFunctionInfo(func, info->script(), info);
633 } 632 }
634 633
635 // Return a null handle if any initial values can't be created. Caller 634 // Return a null handle if any initial values can't be created. Caller
636 // will set stack overflow. 635 // will set stack overflow.
637 if (initial_value.is_null()) return Handle<FixedArray>(); 636 if (initial_value.is_null()) return Handle<FixedArray>();
638 637
639 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt())); 638 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt()));
(...skipping 10 matching lines...) Expand all
650 void set_constant_pool_entry(size_t constant_pool_entry) { 649 void set_constant_pool_entry(size_t constant_pool_entry) {
651 DCHECK(!empty()); 650 DCHECK(!empty());
652 DCHECK(!has_constant_pool_entry_); 651 DCHECK(!has_constant_pool_entry_);
653 constant_pool_entry_ = constant_pool_entry; 652 constant_pool_entry_ = constant_pool_entry;
654 has_constant_pool_entry_ = true; 653 has_constant_pool_entry_ = true;
655 } 654 }
656 655
657 bool empty() { return declarations_.empty(); } 656 bool empty() { return declarations_.empty(); }
658 657
659 private: 658 private:
660 Isolate* isolate_;
661 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_; 659 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_;
662 size_t constant_pool_entry_; 660 size_t constant_pool_entry_;
663 bool has_constant_pool_entry_; 661 bool has_constant_pool_entry_;
664 }; 662 };
665 663
666 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) 664 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
667 : isolate_(info->isolate()), 665 : zone_(info->zone()),
668 zone_(info->zone()),
669 builder_(new (zone()) BytecodeArrayBuilder( 666 builder_(new (zone()) BytecodeArrayBuilder(
670 info->isolate(), info->zone(), info->num_parameters_including_this(), 667 info->isolate(), info->zone(), info->num_parameters_including_this(),
671 info->scope()->MaxNestedContextChainLength(), 668 info->scope()->MaxNestedContextChainLength(),
672 info->scope()->num_stack_slots(), info->literal(), 669 info->scope()->num_stack_slots(), info->literal(),
673 info->SourcePositionRecordingMode())), 670 info->SourcePositionRecordingMode())),
674 info_(info), 671 info_(info),
675 scope_(info->scope()), 672 scope_(info->scope()),
676 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(), 673 isolate_access_allowed_(true),
Michael Starzinger 2016/08/16 12:26:50 nit: Field should no longer be required. Lets drop
rmcilroy 2016/08/16 14:22:30 Oops, done.
677 info->zone())), 674 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
678 global_declarations_(0, info->zone()), 675 global_declarations_(0, info->zone()),
679 function_literals_(0, info->zone()), 676 function_literals_(0, info->zone()),
680 native_function_literals_(0, info->zone()), 677 native_function_literals_(0, info->zone()),
681 execution_control_(nullptr), 678 execution_control_(nullptr),
682 execution_context_(nullptr), 679 execution_context_(nullptr),
683 execution_result_(nullptr), 680 execution_result_(nullptr),
684 register_allocator_(nullptr), 681 register_allocator_(nullptr),
685 generator_resume_points_(info->literal()->yield_count(), info->zone()), 682 generator_resume_points_(info->literal()->yield_count(), info->zone()),
686 generator_state_(), 683 generator_state_(),
687 loop_depth_(0) { 684 loop_depth_(0),
688 InitializeAstVisitor(isolate()->stack_guard()->real_climit()); 685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()),
686 prototype_string_(info->isolate()->factory()->prototype_string()) {
687 InitializeAstVisitor(info->isolate()->stack_guard()->real_climit());
689 } 688 }
690 689
691 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { 690 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(Isolate* isolate) {
692 // Create an inner HandleScope to avoid unnecessarily canonicalizing handles 691 // Create an inner HandleScope to avoid unnecessarily canonicalizing handles
693 // created as part of bytecode finalization. 692 // created as part of bytecode finalization.
694 HandleScope scope(isolate()); 693 HandleScope scope(isolate);
695 694
696 GenerateBytecode(); 695 GenerateBytecode();
697 FinalizeBytecode(); 696 FinalizeBytecode(isolate);
698 697
699 if (HasStackOverflow()) return Handle<BytecodeArray>(); 698 if (HasStackOverflow()) return Handle<BytecodeArray>();
700 699
701 return scope.CloseAndEscape(builder()->ToBytecodeArray()); 700 return scope.CloseAndEscape(builder()->ToBytecodeArray(isolate));
702 } 701 }
703 702
704 void BytecodeGenerator::FinalizeBytecode() { 703 void BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
705 // Build global declaration pair arrays. 704 // Build global declaration pair arrays.
706 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { 705 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
707 Handle<FixedArray> declarations = 706 Handle<FixedArray> declarations =
708 globals_builder->AllocateDeclarationPairs(info()); 707 globals_builder->AllocateDeclarationPairs(info());
709 if (declarations.is_null()) return SetStackOverflow(); 708 if (declarations.is_null()) return SetStackOverflow();
710 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), 709 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
711 declarations); 710 declarations);
712 } 711 }
713 712
714 // Find or build shared function infos. 713 // Find or build shared function infos.
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 builder() 1014 builder()
1016 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry()) 1015 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
1017 .StoreAccumulatorInRegister(pairs) 1016 .StoreAccumulatorInRegister(pairs)
1018 .LoadLiteral(Smi::FromInt(encoded_flags)) 1017 .LoadLiteral(Smi::FromInt(encoded_flags))
1019 .StoreAccumulatorInRegister(flags) 1018 .StoreAccumulatorInRegister(flags)
1020 .MoveRegister(Register::function_closure(), function) 1019 .MoveRegister(Register::function_closure(), function)
1021 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3); 1020 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3);
1022 1021
1023 // Push and reset globals builder. 1022 // Push and reset globals builder.
1024 global_declarations_.push_back(globals_builder()); 1023 global_declarations_.push_back(globals_builder());
1025 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(isolate(), zone()); 1024 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
1026 } 1025 }
1027 1026
1028 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1027 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1029 for (int i = 0; i < statements->length(); i++) { 1028 for (int i = 0; i < statements->length(); i++) {
1030 // Allocate an outer register allocations scope for the statement. 1029 // Allocate an outer register allocations scope for the statement.
1031 RegisterAllocationScope allocation_scope(this); 1030 RegisterAllocationScope allocation_scope(this);
1032 Statement* stmt = statements->at(i); 1031 Statement* stmt = statements->at(i);
1033 Visit(stmt); 1032 Visit(stmt);
1034 if (stmt->IsJump()) break; 1033 if (stmt->IsJump()) break;
1035 } 1034 }
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 execution_result()->SetResultInAccumulator(); 1486 execution_result()->SetResultInAccumulator();
1488 } 1487 }
1489 1488
1490 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { 1489 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
1491 VisitClassLiteralForRuntimeDefinition(expr); 1490 VisitClassLiteralForRuntimeDefinition(expr);
1492 1491
1493 // Load the "prototype" from the constructor. 1492 // Load the "prototype" from the constructor.
1494 register_allocator()->PrepareForConsecutiveAllocations(2); 1493 register_allocator()->PrepareForConsecutiveAllocations(2);
1495 Register literal = register_allocator()->NextConsecutiveRegister(); 1494 Register literal = register_allocator()->NextConsecutiveRegister();
1496 Register prototype = register_allocator()->NextConsecutiveRegister(); 1495 Register prototype = register_allocator()->NextConsecutiveRegister();
1497 Handle<String> name = isolate()->factory()->prototype_string();
1498 FeedbackVectorSlot slot = expr->PrototypeSlot(); 1496 FeedbackVectorSlot slot = expr->PrototypeSlot();
1499 builder() 1497 builder()
1500 ->StoreAccumulatorInRegister(literal) 1498 ->StoreAccumulatorInRegister(literal)
1501 .LoadNamedProperty(literal, name, feedback_index(slot)) 1499 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot))
1502 .StoreAccumulatorInRegister(prototype); 1500 .StoreAccumulatorInRegister(prototype);
1503 1501
1504 VisitClassLiteralProperties(expr, literal, prototype); 1502 VisitClassLiteralProperties(expr, literal, prototype);
1505 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); 1503 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1);
1506 // Assign to class variable. 1504 // Assign to class variable.
1507 if (expr->class_variable_proxy() != nullptr) { 1505 if (expr->class_variable_proxy() != nullptr) {
1508 Variable* var = expr->class_variable_proxy()->var(); 1506 Variable* var = expr->class_variable_proxy()->var();
1509 FeedbackVectorSlot slot = expr->NeedsProxySlot() 1507 FeedbackVectorSlot slot = expr->NeedsProxySlot()
1510 ? expr->ProxySlot() 1508 ? expr->ProxySlot()
1511 : FeedbackVectorSlot::Invalid(); 1509 : FeedbackVectorSlot::Invalid();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 break; 1607 break;
1610 } 1608 }
1611 } 1609 }
1612 } 1610 }
1613 } 1611 }
1614 1612
1615 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( 1613 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName(
1616 Register key) { 1614 Register key) {
1617 BytecodeLabel done; 1615 BytecodeLabel done;
1618 builder() 1616 builder()
1619 ->LoadLiteral(isolate()->factory()->prototype_string()) 1617 ->LoadLiteral(prototype_string())
1620 .CompareOperation(Token::Value::EQ_STRICT, key) 1618 .CompareOperation(Token::Value::EQ_STRICT, key)
1621 .JumpIfFalse(&done) 1619 .JumpIfFalse(&done)
1622 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) 1620 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0)
1623 .Bind(&done); 1621 .Bind(&done);
1624 } 1622 }
1625 1623
1626 void BytecodeGenerator::VisitNativeFunctionLiteral( 1624 void BytecodeGenerator::VisitNativeFunctionLiteral(
1627 NativeFunctionLiteral* expr) { 1625 NativeFunctionLiteral* expr) {
1628 size_t entry = builder()->AllocateConstantPoolEntry(); 1626 size_t entry = builder()->AllocateConstantPoolEntry();
1629 builder()->CreateClosure(entry, NOT_TENURED); 1627 builder()->CreateClosure(entry, NOT_TENURED);
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
3162 3160
3163 // Allocate a new local context. 3161 // Allocate a new local context.
3164 if (scope->is_script_scope()) { 3162 if (scope->is_script_scope()) {
3165 RegisterAllocationScope register_scope(this); 3163 RegisterAllocationScope register_scope(this);
3166 Register closure = register_allocator()->NewRegister(); 3164 Register closure = register_allocator()->NewRegister();
3167 Register scope_info = register_allocator()->NewRegister(); 3165 Register scope_info = register_allocator()->NewRegister();
3168 DCHECK(Register::AreContiguous(closure, scope_info)); 3166 DCHECK(Register::AreContiguous(closure, scope_info));
3169 builder() 3167 builder()
3170 ->LoadAccumulatorWithRegister(Register::function_closure()) 3168 ->LoadAccumulatorWithRegister(Register::function_closure())
3171 .StoreAccumulatorInRegister(closure) 3169 .StoreAccumulatorInRegister(closure)
3172 .LoadLiteral(scope->GetScopeInfo(isolate())) 3170 .LoadLiteral(scope->scope_info())
3173 .StoreAccumulatorInRegister(scope_info) 3171 .StoreAccumulatorInRegister(scope_info)
3174 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 3172 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
3175 } else { 3173 } else {
3176 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 3174 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
3177 builder()->CreateFunctionContext(slot_count); 3175 builder()->CreateFunctionContext(slot_count);
3178 } 3176 }
3179 execution_result()->SetResultInAccumulator(); 3177 execution_result()->SetResultInAccumulator();
3180 } 3178 }
3181 3179
3182 void BytecodeGenerator::VisitBuildLocalActivationContext() { 3180 void BytecodeGenerator::VisitBuildLocalActivationContext() {
(...skipping 27 matching lines...) Expand all
3210 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { 3208 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
3211 AccumulatorResultScope accumulator_execution_result(this); 3209 AccumulatorResultScope accumulator_execution_result(this);
3212 DCHECK(scope->is_block_scope()); 3210 DCHECK(scope->is_block_scope());
3213 3211
3214 // Allocate a new local block context. 3212 // Allocate a new local block context.
3215 register_allocator()->PrepareForConsecutiveAllocations(2); 3213 register_allocator()->PrepareForConsecutiveAllocations(2);
3216 Register scope_info = register_allocator()->NextConsecutiveRegister(); 3214 Register scope_info = register_allocator()->NextConsecutiveRegister();
3217 Register closure = register_allocator()->NextConsecutiveRegister(); 3215 Register closure = register_allocator()->NextConsecutiveRegister();
3218 3216
3219 builder() 3217 builder()
3220 ->LoadLiteral(scope->GetScopeInfo(isolate())) 3218 ->LoadLiteral(scope->scope_info())
3221 .StoreAccumulatorInRegister(scope_info); 3219 .StoreAccumulatorInRegister(scope_info);
3222 VisitFunctionClosureForContext(); 3220 VisitFunctionClosureForContext();
3223 builder() 3221 builder()
3224 ->StoreAccumulatorInRegister(closure) 3222 ->StoreAccumulatorInRegister(closure)
3225 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); 3223 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2);
3226 execution_result()->SetResultInAccumulator(); 3224 execution_result()->SetResultInAccumulator();
3227 } 3225 }
3228 3226
3229 void BytecodeGenerator::VisitNewLocalWithContext() { 3227 void BytecodeGenerator::VisitNewLocalWithContext() {
3230 AccumulatorResultScope accumulator_execution_result(this); 3228 AccumulatorResultScope accumulator_execution_result(this);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3270 builder()->StoreAccumulatorInRegister(value_out); 3268 builder()->StoreAccumulatorInRegister(value_out);
3271 VisitSetHomeObject(value_out, home_object, property); 3269 VisitSetHomeObject(value_out, home_object, property);
3272 } 3270 }
3273 } 3271 }
3274 3272
3275 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 3273 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
3276 ObjectLiteralProperty* property, 3274 ObjectLiteralProperty* property,
3277 int slot_number) { 3275 int slot_number) {
3278 Expression* expr = property->value(); 3276 Expression* expr = property->value();
3279 if (FunctionLiteral::NeedsHomeObject(expr)) { 3277 if (FunctionLiteral::NeedsHomeObject(expr)) {
3280 Handle<Name> name = isolate()->factory()->home_object_symbol();
3281 FeedbackVectorSlot slot = property->GetSlot(slot_number); 3278 FeedbackVectorSlot slot = property->GetSlot(slot_number);
3282 builder() 3279 builder()
3283 ->LoadAccumulatorWithRegister(home_object) 3280 ->LoadAccumulatorWithRegister(home_object)
3284 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); 3281 .StoreNamedProperty(value, home_object_symbol(), feedback_index(slot),
3282 language_mode());
3285 } 3283 }
3286 } 3284 }
3287 3285
3288 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { 3286 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
3289 if (variable == nullptr) return; 3287 if (variable == nullptr) return;
3290 3288
3291 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); 3289 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
3292 3290
3293 // Allocate and initialize a new arguments object and assign to the 3291 // Allocate and initialize a new arguments object and assign to the
3294 // {arguments} variable. 3292 // {arguments} variable.
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3431 return execution_context()->scope()->language_mode(); 3429 return execution_context()->scope()->language_mode();
3432 } 3430 }
3433 3431
3434 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3432 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3435 return TypeFeedbackVector::GetIndex(slot); 3433 return TypeFeedbackVector::GetIndex(slot);
3436 } 3434 }
3437 3435
3438 } // namespace interpreter 3436 } // namespace interpreter
3439 } // namespace internal 3437 } // namespace internal
3440 } // namespace v8 3438 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698