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

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

Issue 1587033002: [Interpreter] Ensure we always have an outer register allocation scope. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_mythri
Patch Set: Similarity 20 Created 4 years, 11 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
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-register-allocator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/compiler.h" 8 #include "src/compiler.h"
9 #include "src/interpreter/bytecode-register-allocator.h"
9 #include "src/interpreter/control-flow-builders.h" 10 #include "src/interpreter/control-flow-builders.h"
10 #include "src/objects.h" 11 #include "src/objects.h"
11 #include "src/parsing/parser.h" 12 #include "src/parsing/parser.h"
12 #include "src/parsing/token.h" 13 #include "src/parsing/token.h"
13 14
14 namespace v8 { 15 namespace v8 {
15 namespace internal { 16 namespace internal {
16 namespace interpreter { 17 namespace interpreter {
17 18
18 19
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 Statement* statement) { 171 Statement* statement) {
171 ControlScope* current = this; 172 ControlScope* current = this;
172 do { 173 do {
173 if (current->Execute(command, statement)) return; 174 if (current->Execute(command, statement)) return;
174 current = current->outer(); 175 current = current->outer();
175 } while (current != nullptr); 176 } while (current != nullptr);
176 UNREACHABLE(); 177 UNREACHABLE();
177 } 178 }
178 179
179 180
180 // Scoped base class for determining where the result of an expression 181 class BytecodeGenerator::RegisterAllocationScope {
181 // is stored.
182 class BytecodeGenerator::ExpressionResultScope {
183 public: 182 public:
184 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind) 183 explicit RegisterAllocationScope(BytecodeGenerator* generator)
185 : generator_(generator), 184 : generator_(generator),
186 kind_(kind), 185 outer_(generator->register_allocator()),
187 outer_(generator->execution_result()), 186 allocator_(builder()) {
188 allocator_(builder()), 187 generator_->set_register_allocator(this);
189 result_identified_(false) {
190 generator_->set_execution_result(this);
191 } 188 }
192 189
193 virtual ~ExpressionResultScope() { 190 virtual ~RegisterAllocationScope() {
194 generator_->set_execution_result(outer_); 191 generator_->set_register_allocator(outer_);
195 DCHECK(result_identified());
196 } 192 }
197 193
198 bool IsEffect() const { return kind_ == Expression::kEffect; }
199 bool IsValue() const { return kind_ == Expression::kValue; }
200
201 virtual void SetResultInAccumulator() = 0;
202 virtual void SetResultInRegister(Register reg) = 0;
203
204 BytecodeGenerator* generator() const { return generator_; }
205 BytecodeArrayBuilder* builder() const { return generator()->builder(); }
206 ExpressionResultScope* outer() const { return outer_; }
207
208 Register NewRegister() { 194 Register NewRegister() {
209 ExpressionResultScope* current_scope = generator()->execution_result(); 195 RegisterAllocationScope* current_scope = generator()->register_allocator();
210 if ((current_scope == this) || 196 if ((current_scope == this) ||
211 (current_scope->outer() == this && 197 (current_scope->outer() == this &&
212 !current_scope->allocator_.hasConsecutiveAllocations())) { 198 !current_scope->allocator_.HasConsecutiveAllocations())) {
213 // Regular case - Allocating registers in current or outer context. 199 // Regular case - Allocating registers in current or outer context.
214 // VisitForRegisterValue allocates register in outer context. 200 // VisitForRegisterValue allocates register in outer context.
215 return allocator_.NewRegister(); 201 return allocator_.NewRegister();
216 } else { 202 } else {
217 // If it is required to allocate a register other than current or outer 203 // If it is required to allocate a register other than current or outer
218 // scopes, allocate a new temporary register. It might be expensive to 204 // scopes, allocate a new temporary register. It might be expensive to
219 // walk the full context chain and compute the list of consecutive 205 // walk the full context chain and compute the list of consecutive
220 // reservations in the innerscopes. 206 // reservations in the innerscopes.
221 UNIMPLEMENTED(); 207 UNIMPLEMENTED();
222 return Register(-1); 208 return Register(-1);
223 } 209 }
224 } 210 }
225 211
226 void PrepareForConsecutiveAllocations(size_t count) { 212 void PrepareForConsecutiveAllocations(size_t count) {
227 allocator_.PrepareForConsecutiveAllocations(count); 213 allocator_.PrepareForConsecutiveAllocations(count);
228 } 214 }
229 215
230 Register NextConsecutiveRegister() { 216 Register NextConsecutiveRegister() {
231 return allocator_.NextConsecutiveRegister(); 217 return allocator_.NextConsecutiveRegister();
232 } 218 }
233 219
220 bool RegisterIsAllocatedInThisScope(Register reg) const {
221 return allocator_.RegisterIsAllocatedInThisScope(reg);
222 }
223
224 RegisterAllocationScope* outer() const { return outer_; }
225
226 private:
227 BytecodeGenerator* generator() const { return generator_; }
228 BytecodeArrayBuilder* builder() const { return generator_->builder(); }
229
230 BytecodeGenerator* generator_;
231 RegisterAllocationScope* outer_;
232 BytecodeRegisterAllocator allocator_;
233
234 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
235 };
236
237
238 // Scoped base class for determining where the result of an expression
239 // is stored.
240 class BytecodeGenerator::ExpressionResultScope {
241 public:
242 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
243 : generator_(generator),
244 kind_(kind),
245 outer_(generator->execution_result()),
246 allocator_(generator),
247 result_identified_(false) {
248 generator_->set_execution_result(this);
249 }
250
251 virtual ~ExpressionResultScope() {
252 generator_->set_execution_result(outer_);
253 DCHECK(result_identified());
254 }
255
256 bool IsEffect() const { return kind_ == Expression::kEffect; }
257 bool IsValue() const { return kind_ == Expression::kValue; }
258
259 virtual void SetResultInAccumulator() = 0;
260 virtual void SetResultInRegister(Register reg) = 0;
261
234 protected: 262 protected:
263 ExpressionResultScope* outer() const { return outer_; }
264 BytecodeArrayBuilder* builder() const { return generator_->builder(); }
265 const RegisterAllocationScope* allocator() const { return &allocator_; }
266
235 void set_result_identified() { 267 void set_result_identified() {
236 DCHECK(!result_identified()); 268 DCHECK(!result_identified());
237 result_identified_ = true; 269 result_identified_ = true;
238 } 270 }
239 271
240 bool result_identified() const { return result_identified_; } 272 bool result_identified() const { return result_identified_; }
241 273
242 const TemporaryRegisterScope* allocator() const { return &allocator_; }
243
244 private: 274 private:
245 BytecodeGenerator* generator_; 275 BytecodeGenerator* generator_;
246 Expression::Context kind_; 276 Expression::Context kind_;
247 ExpressionResultScope* outer_; 277 ExpressionResultScope* outer_;
248 TemporaryRegisterScope allocator_; 278 RegisterAllocationScope allocator_;
249 bool result_identified_; 279 bool result_identified_;
250 280
251 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope); 281 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
252 }; 282 };
253 283
254 284
255 // Scoped class used when the result of the current expression is not 285 // Scoped class used when the result of the current expression is not
256 // expected to produce a result. 286 // expected to produce a result.
257 class BytecodeGenerator::EffectResultScope final 287 class BytecodeGenerator::EffectResultScope final
258 : public ExpressionResultScope { 288 : public ExpressionResultScope {
(...skipping 27 matching lines...) Expand all
286 316
287 // Scoped class used when the result of the current expression to be 317 // Scoped class used when the result of the current expression to be
288 // evaluated should go into an interpreter register. 318 // evaluated should go into an interpreter register.
289 class BytecodeGenerator::RegisterResultScope final 319 class BytecodeGenerator::RegisterResultScope final
290 : public ExpressionResultScope { 320 : public ExpressionResultScope {
291 public: 321 public:
292 explicit RegisterResultScope(BytecodeGenerator* generator) 322 explicit RegisterResultScope(BytecodeGenerator* generator)
293 : ExpressionResultScope(generator, Expression::kValue) {} 323 : ExpressionResultScope(generator, Expression::kValue) {}
294 324
295 virtual void SetResultInAccumulator() { 325 virtual void SetResultInAccumulator() {
296 result_register_ = outer()->NewRegister(); 326 result_register_ = allocator()->outer()->NewRegister();
297 builder()->StoreAccumulatorInRegister(result_register_); 327 builder()->StoreAccumulatorInRegister(result_register_);
298 set_result_identified(); 328 set_result_identified();
299 } 329 }
300 330
301 virtual void SetResultInRegister(Register reg) { 331 virtual void SetResultInRegister(Register reg) {
302 DCHECK(builder()->RegisterIsParameterOrLocal(reg) || 332 DCHECK(builder()->RegisterIsParameterOrLocal(reg) ||
303 (builder()->RegisterIsTemporary(reg) && 333 (builder()->RegisterIsTemporary(reg) &&
304 !allocator()->RegisterIsAllocatedInThisScope(reg))); 334 !allocator()->RegisterIsAllocatedInThisScope(reg)));
305 result_register_ = reg; 335 result_register_ = reg;
306 set_result_identified(); 336 set_result_identified();
307 } 337 }
308 338
309 Register ResultRegister() const { return result_register_; } 339 Register ResultRegister() const { return result_register_; }
310 340
311 private: 341 private:
312 Register result_register_; 342 Register result_register_;
313 }; 343 };
314 344
315 345
316 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) 346 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
317 : isolate_(isolate), 347 : isolate_(isolate),
318 zone_(zone), 348 zone_(zone),
319 builder_(isolate, zone), 349 builder_(isolate, zone),
320 info_(nullptr), 350 info_(nullptr),
321 scope_(nullptr), 351 scope_(nullptr),
322 globals_(0, zone), 352 globals_(0, zone),
323 execution_control_(nullptr), 353 execution_control_(nullptr),
324 execution_context_(nullptr), 354 execution_context_(nullptr),
325 execution_result_(nullptr) { 355 execution_result_(nullptr),
356 register_allocator_(nullptr) {
326 InitializeAstVisitor(isolate); 357 InitializeAstVisitor(isolate);
327 } 358 }
328 359
329 360
330 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { 361 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
331 set_info(info); 362 set_info(info);
332 set_scope(info->scope()); 363 set_scope(info->scope());
333 364
334 // Initialize the incoming context. 365 // Initialize the incoming context.
335 ContextScope incoming_context(this, scope(), false); 366 ContextScope incoming_context(this, scope(), false);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 524 }
494 525
495 526
496 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { 527 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
497 UNIMPLEMENTED(); 528 UNIMPLEMENTED();
498 } 529 }
499 530
500 531
501 void BytecodeGenerator::VisitDeclarations( 532 void BytecodeGenerator::VisitDeclarations(
502 ZoneList<Declaration*>* declarations) { 533 ZoneList<Declaration*>* declarations) {
534 RegisterAllocationScope register_scope(this);
503 DCHECK(globals()->empty()); 535 DCHECK(globals()->empty());
504 AstVisitor::VisitDeclarations(declarations); 536 AstVisitor::VisitDeclarations(declarations);
505 if (globals()->empty()) return; 537 if (globals()->empty()) return;
506 int array_index = 0; 538 int array_index = 0;
507 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( 539 Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
508 static_cast<int>(globals()->size()), TENURED); 540 static_cast<int>(globals()->size()), TENURED);
509 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); 541 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
510 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | 542 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
511 DeclareGlobalsNativeFlag::encode(info()->is_native()) | 543 DeclareGlobalsNativeFlag::encode(info()->is_native()) |
512 DeclareGlobalsLanguageMode::encode(language_mode()); 544 DeclareGlobalsLanguageMode::encode(language_mode());
513 545
514 TemporaryRegisterScope temporary_register_scope(builder()); 546 Register pairs = register_allocator()->NewRegister();
515 Register pairs = temporary_register_scope.NewRegister();
516 builder()->LoadLiteral(data); 547 builder()->LoadLiteral(data);
517 builder()->StoreAccumulatorInRegister(pairs); 548 builder()->StoreAccumulatorInRegister(pairs);
518 549
519 Register flags = temporary_register_scope.NewRegister(); 550 Register flags = register_allocator()->NewRegister();
520 builder()->LoadLiteral(Smi::FromInt(encoded_flags)); 551 builder()->LoadLiteral(Smi::FromInt(encoded_flags));
521 builder()->StoreAccumulatorInRegister(flags); 552 builder()->StoreAccumulatorInRegister(flags);
522 DCHECK(flags.index() == pairs.index() + 1); 553 DCHECK(flags.index() == pairs.index() + 1);
523 554
524 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2); 555 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
525 globals()->clear(); 556 globals()->clear();
526 } 557 }
527 558
528 559
560 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
561 for (int i = 0; i < statements->length(); i++) {
562 // Allocate an outer register allocations scope for the statement.
563 RegisterAllocationScope allocation_scope(this);
564 Statement* stmt = statements->at(i);
565 Visit(stmt);
566 if (stmt->IsJump()) break;
567 }
568 }
569
570
529 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 571 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
530 EffectResultScope statement_result_scope(this);
531 VisitForEffect(stmt->expression()); 572 VisitForEffect(stmt->expression());
532 } 573 }
533 574
534 575
535 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 576 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
536 } 577 }
537 578
538 579
539 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 580 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
540 BytecodeLabel else_label, end_label; 581 BytecodeLabel else_label, end_label;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 execution_control()->Continue(stmt->target()); 616 execution_control()->Continue(stmt->target());
576 } 617 }
577 618
578 619
579 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 620 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
580 execution_control()->Break(stmt->target()); 621 execution_control()->Break(stmt->target());
581 } 622 }
582 623
583 624
584 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 625 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
585 EffectResultScope statement_result_scope(this);
586 VisitForAccumulatorValue(stmt->expression()); 626 VisitForAccumulatorValue(stmt->expression());
587 builder()->Return(); 627 builder()->Return();
588 } 628 }
589 629
590 630
591 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 631 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
592 UNIMPLEMENTED(); 632 UNIMPLEMENTED();
593 } 633 }
594 634
595 635
596 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 636 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
597 // We need this scope because we visit for register values. We have to 637 // We need this scope because we visit for register values. We have to
598 // maintain a execution result scope where registers can be allocated. 638 // maintain a execution result scope where registers can be allocated.
599 EffectResultScope effect_results_scope(this);
600 ZoneList<CaseClause*>* clauses = stmt->cases(); 639 ZoneList<CaseClause*>* clauses = stmt->cases();
601 SwitchBuilder switch_builder(builder(), clauses->length()); 640 SwitchBuilder switch_builder(builder(), clauses->length());
602 ControlScopeForBreakable scope(this, stmt, &switch_builder); 641 ControlScopeForBreakable scope(this, stmt, &switch_builder);
603 int default_index = -1; 642 int default_index = -1;
604 643
605 // Keep the switch value in a register until a case matches. 644 // Keep the switch value in a register until a case matches.
606 Register tag = VisitForRegisterValue(stmt->tag()); 645 Register tag = VisitForRegisterValue(stmt->tag());
607 646
608 // Iterate over all cases and create nodes for label comparison. 647 // Iterate over all cases and create nodes for label comparison.
609 BytecodeLabel done_label; 648 BytecodeLabel done_label;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 // accumulator. 767 // accumulator.
729 Property* property = expr->AsProperty(); 768 Property* property = expr->AsProperty();
730 LhsKind assign_type = Property::GetAssignType(property); 769 LhsKind assign_type = Property::GetAssignType(property);
731 switch (assign_type) { 770 switch (assign_type) {
732 case VARIABLE: { 771 case VARIABLE: {
733 Variable* variable = expr->AsVariableProxy()->var(); 772 Variable* variable = expr->AsVariableProxy()->var();
734 VisitVariableAssignment(variable, slot); 773 VisitVariableAssignment(variable, slot);
735 break; 774 break;
736 } 775 }
737 case NAMED_PROPERTY: { 776 case NAMED_PROPERTY: {
738 TemporaryRegisterScope temporary_register_scope(builder()); 777 RegisterAllocationScope register_scope(this);
739 Register value = temporary_register_scope.NewRegister(); 778 Register value = register_allocator()->NewRegister();
740 builder()->StoreAccumulatorInRegister(value); 779 builder()->StoreAccumulatorInRegister(value);
741 Register object = VisitForRegisterValue(property->obj()); 780 Register object = VisitForRegisterValue(property->obj());
742 Handle<String> name = property->key()->AsLiteral()->AsPropertyName(); 781 Handle<String> name = property->key()->AsLiteral()->AsPropertyName();
743 builder()->LoadAccumulatorWithRegister(value); 782 builder()->LoadAccumulatorWithRegister(value);
744 builder()->StoreNamedProperty(object, name, feedback_index(slot), 783 builder()->StoreNamedProperty(object, name, feedback_index(slot),
745 language_mode()); 784 language_mode());
746 break; 785 break;
747 } 786 }
748 case KEYED_PROPERTY: { 787 case KEYED_PROPERTY: {
749 TemporaryRegisterScope temporary_register_scope(builder()); 788 RegisterAllocationScope register_scope(this);
750 Register value = temporary_register_scope.NewRegister(); 789 Register value = register_allocator()->NewRegister();
751 builder()->StoreAccumulatorInRegister(value); 790 builder()->StoreAccumulatorInRegister(value);
752 Register object = VisitForRegisterValue(property->obj()); 791 Register object = VisitForRegisterValue(property->obj());
753 Register key = VisitForRegisterValue(property->key()); 792 Register key = VisitForRegisterValue(property->key());
754 builder()->LoadAccumulatorWithRegister(value); 793 builder()->LoadAccumulatorWithRegister(value);
755 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 794 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
756 language_mode()); 795 language_mode());
757 break; 796 break;
758 } 797 }
759 case NAMED_SUPER_PROPERTY: 798 case NAMED_SUPER_PROPERTY:
760 case KEYED_SUPER_PROPERTY: 799 case KEYED_SUPER_PROPERTY:
761 UNIMPLEMENTED(); 800 UNIMPLEMENTED();
762 } 801 }
763 } 802 }
764 803
765 804
766 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 805 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
767 EffectResultScope statement_result_scope(this);
768 if (stmt->subject()->IsNullLiteral() || 806 if (stmt->subject()->IsNullLiteral() ||
769 stmt->subject()->IsUndefinedLiteral(isolate())) { 807 stmt->subject()->IsUndefinedLiteral(isolate())) {
770 // ForIn generates lots of code, skip if it wouldn't produce any effects. 808 // ForIn generates lots of code, skip if it wouldn't produce any effects.
771 return; 809 return;
772 } 810 }
773 811
774 LoopBuilder loop_builder(builder()); 812 LoopBuilder loop_builder(builder());
775 ControlScopeForIteration control_scope(this, stmt, &loop_builder); 813 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
776 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; 814 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label;
777 815
778 // Prepare the state for executing ForIn. 816 // Prepare the state for executing ForIn.
779 VisitForAccumulatorValue(stmt->subject()); 817 VisitForAccumulatorValue(stmt->subject());
780 builder()->JumpIfUndefined(&subject_undefined_label); 818 builder()->JumpIfUndefined(&subject_undefined_label);
781 builder()->JumpIfNull(&subject_null_label); 819 builder()->JumpIfNull(&subject_null_label);
782 Register receiver = execution_result()->NewRegister(); 820 Register receiver = register_allocator()->NewRegister();
783 builder()->CastAccumulatorToJSObject(); 821 builder()->CastAccumulatorToJSObject();
784 builder()->JumpIfNull(&not_object_label); 822 builder()->JumpIfNull(&not_object_label);
785 builder()->StoreAccumulatorInRegister(receiver); 823 builder()->StoreAccumulatorInRegister(receiver);
786 Register cache_type = execution_result()->NewRegister(); 824 Register cache_type = register_allocator()->NewRegister();
787 Register cache_array = execution_result()->NewRegister(); 825 Register cache_array = register_allocator()->NewRegister();
788 Register cache_length = execution_result()->NewRegister(); 826 Register cache_length = register_allocator()->NewRegister();
789 builder()->ForInPrepare(cache_type, cache_array, cache_length); 827 builder()->ForInPrepare(cache_type, cache_array, cache_length);
790 828
791 // Set up loop counter 829 // Set up loop counter
792 Register index = execution_result()->NewRegister(); 830 Register index = register_allocator()->NewRegister();
793 builder()->LoadLiteral(Smi::FromInt(0)); 831 builder()->LoadLiteral(Smi::FromInt(0));
794 builder()->StoreAccumulatorInRegister(index); 832 builder()->StoreAccumulatorInRegister(index);
795 833
796 // The loop 834 // The loop
797 loop_builder.LoopHeader(); 835 loop_builder.LoopHeader();
798 loop_builder.Condition(); 836 loop_builder.Condition();
799 builder()->ForInDone(index, cache_length); 837 builder()->ForInDone(index, cache_length);
800 loop_builder.BreakIfTrue(); 838 loop_builder.BreakIfTrue();
801 builder()->ForInNext(receiver, cache_type, cache_array, index); 839 builder()->ForInNext(receiver, cache_type, cache_array, index);
802 loop_builder.ContinueIfUndefined(); 840 loop_builder.ContinueIfUndefined();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 } else { 946 } else {
909 builder()->LoadLiteral(value); 947 builder()->LoadLiteral(value);
910 } 948 }
911 execution_result()->SetResultInAccumulator(); 949 execution_result()->SetResultInAccumulator();
912 } 950 }
913 } 951 }
914 952
915 953
916 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 954 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
917 // Materialize a regular expression literal. 955 // Materialize a regular expression literal.
918 TemporaryRegisterScope temporary_register_scope(builder());
919 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(), 956 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
920 expr->flags()); 957 expr->flags());
921 execution_result()->SetResultInAccumulator(); 958 execution_result()->SetResultInAccumulator();
922 } 959 }
923 960
924 961
925 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 962 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
926 // Deep-copy the literal boilerplate. 963 // Deep-copy the literal boilerplate.
927 builder()->CreateObjectLiteral(expr->constant_properties(), 964 builder()->CreateObjectLiteral(expr->constant_properties(),
928 expr->literal_index(), 965 expr->literal_index(),
929 expr->ComputeFlags(true)); 966 expr->ComputeFlags(true));
930
931 TemporaryRegisterScope temporary_register_scope(builder());
932 Register literal; 967 Register literal;
933 968
934 // Store computed values into the literal. 969 // Store computed values into the literal.
935 bool literal_in_accumulator = true; 970 bool literal_in_accumulator = true;
936 int property_index = 0; 971 int property_index = 0;
937 AccessorTable accessor_table(zone()); 972 AccessorTable accessor_table(zone());
938 for (; property_index < expr->properties()->length(); property_index++) { 973 for (; property_index < expr->properties()->length(); property_index++) {
939 TemporaryRegisterScope inner_temporary_register_scope(builder());
940 ObjectLiteral::Property* property = expr->properties()->at(property_index); 974 ObjectLiteral::Property* property = expr->properties()->at(property_index);
941 if (property->is_computed_name()) break; 975 if (property->is_computed_name()) break;
942 if (property->IsCompileTimeValue()) continue; 976 if (property->IsCompileTimeValue()) continue;
943 977
944 if (literal_in_accumulator) { 978 if (literal_in_accumulator) {
945 literal = temporary_register_scope.NewRegister(); 979 literal = register_allocator()->NewRegister();
946 builder()->StoreAccumulatorInRegister(literal); 980 builder()->StoreAccumulatorInRegister(literal);
947 literal_in_accumulator = false; 981 literal_in_accumulator = false;
948 } 982 }
949 983
984 RegisterAllocationScope inner_register_scope(this);
950 Literal* literal_key = property->key()->AsLiteral(); 985 Literal* literal_key = property->key()->AsLiteral();
951 switch (property->kind()) { 986 switch (property->kind()) {
952 case ObjectLiteral::Property::CONSTANT: 987 case ObjectLiteral::Property::CONSTANT:
953 UNREACHABLE(); 988 UNREACHABLE();
954 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 989 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
955 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 990 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
956 // Fall through. 991 // Fall through.
957 case ObjectLiteral::Property::COMPUTED: { 992 case ObjectLiteral::Property::COMPUTED: {
958 // It is safe to use [[Put]] here because the boilerplate already 993 // It is safe to use [[Put]] here because the boilerplate already
959 // contains computed properties with an uninitialized value. 994 // contains computed properties with an uninitialized value.
960 if (literal_key->value()->IsInternalizedString()) { 995 if (literal_key->value()->IsInternalizedString()) {
961 if (property->emit_store()) { 996 if (property->emit_store()) {
962 VisitForAccumulatorValue(property->value()); 997 VisitForAccumulatorValue(property->value());
963 builder()->StoreNamedProperty( 998 builder()->StoreNamedProperty(
964 literal, literal_key->AsPropertyName(), 999 literal, literal_key->AsPropertyName(),
965 feedback_index(property->GetSlot(0)), language_mode()); 1000 feedback_index(property->GetSlot(0)), language_mode());
966 } else { 1001 } else {
967 VisitForEffect(property->value()); 1002 VisitForEffect(property->value());
968 } 1003 }
969 } else { 1004 } else {
970 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3); 1005 register_allocator()->PrepareForConsecutiveAllocations(3);
971 Register key = 1006 Register key = register_allocator()->NextConsecutiveRegister();
972 inner_temporary_register_scope.NextConsecutiveRegister(); 1007 Register value = register_allocator()->NextConsecutiveRegister();
973 Register value = 1008 Register language = register_allocator()->NextConsecutiveRegister();
974 inner_temporary_register_scope.NextConsecutiveRegister();
975 Register language =
976 inner_temporary_register_scope.NextConsecutiveRegister();
977 // TODO(oth): This is problematic - can't assume contiguous here. 1009 // TODO(oth): This is problematic - can't assume contiguous here.
978 // literal is allocated in temporary_register_scope, whereas 1010 // literal is allocated in outer register scope, whereas key, value,
979 // key, value, language are in another. 1011 // language are in another.
980 DCHECK(Register::AreContiguous(literal, key, value, language)); 1012 DCHECK(Register::AreContiguous(literal, key, value, language));
981 VisitForAccumulatorValue(property->key()); 1013 VisitForAccumulatorValue(property->key());
982 builder()->StoreAccumulatorInRegister(key); 1014 builder()->StoreAccumulatorInRegister(key);
983 VisitForAccumulatorValue(property->value()); 1015 VisitForAccumulatorValue(property->value());
984 builder()->StoreAccumulatorInRegister(value); 1016 builder()->StoreAccumulatorInRegister(value);
985 if (property->emit_store()) { 1017 if (property->emit_store()) {
986 builder() 1018 builder()
987 ->LoadLiteral(Smi::FromInt(SLOPPY)) 1019 ->LoadLiteral(Smi::FromInt(SLOPPY))
988 .StoreAccumulatorInRegister(language) 1020 .StoreAccumulatorInRegister(language)
989 .CallRuntime(Runtime::kSetProperty, literal, 4); 1021 .CallRuntime(Runtime::kSetProperty, literal, 4);
990 VisitSetHomeObject(value, literal, property); 1022 VisitSetHomeObject(value, literal, property);
991 } 1023 }
992 } 1024 }
993 break; 1025 break;
994 } 1026 }
995 case ObjectLiteral::Property::PROTOTYPE: { 1027 case ObjectLiteral::Property::PROTOTYPE: {
996 inner_temporary_register_scope.PrepareForConsecutiveAllocations(1); 1028 register_allocator()->PrepareForConsecutiveAllocations(1);
997 DCHECK(property->emit_store()); 1029 DCHECK(property->emit_store());
998 Register value = 1030 Register value = register_allocator()->NextConsecutiveRegister();
999 inner_temporary_register_scope.NextConsecutiveRegister();
1000 DCHECK(Register::AreContiguous(literal, value)); 1031 DCHECK(Register::AreContiguous(literal, value));
1001 VisitForAccumulatorValue(property->value()); 1032 VisitForAccumulatorValue(property->value());
1002 builder()->StoreAccumulatorInRegister(value).CallRuntime( 1033 builder()->StoreAccumulatorInRegister(value).CallRuntime(
1003 Runtime::kInternalSetPrototype, literal, 2); 1034 Runtime::kInternalSetPrototype, literal, 2);
1004 break; 1035 break;
1005 } 1036 }
1006 case ObjectLiteral::Property::GETTER: 1037 case ObjectLiteral::Property::GETTER:
1007 if (property->emit_store()) { 1038 if (property->emit_store()) {
1008 accessor_table.lookup(literal_key)->second->getter = property; 1039 accessor_table.lookup(literal_key)->second->getter = property;
1009 } 1040 }
1010 break; 1041 break;
1011 case ObjectLiteral::Property::SETTER: 1042 case ObjectLiteral::Property::SETTER:
1012 if (property->emit_store()) { 1043 if (property->emit_store()) {
1013 accessor_table.lookup(literal_key)->second->setter = property; 1044 accessor_table.lookup(literal_key)->second->setter = property;
1014 } 1045 }
1015 break; 1046 break;
1016 } 1047 }
1017 } 1048 }
1018 1049
1019 // Define accessors, using only a single call to the runtime for each pair of 1050 // Define accessors, using only a single call to the runtime for each pair of
1020 // corresponding getters and setters. 1051 // corresponding getters and setters.
1021 for (AccessorTable::Iterator it = accessor_table.begin(); 1052 for (AccessorTable::Iterator it = accessor_table.begin();
1022 it != accessor_table.end(); ++it) { 1053 it != accessor_table.end(); ++it) {
1023 TemporaryRegisterScope inner_temporary_register_scope(builder()); 1054 RegisterAllocationScope inner_register_scope(this);
1024 inner_temporary_register_scope.PrepareForConsecutiveAllocations(4); 1055 register_allocator()->PrepareForConsecutiveAllocations(4);
1025 Register name = inner_temporary_register_scope.NextConsecutiveRegister(); 1056 Register name = register_allocator()->NextConsecutiveRegister();
1026 Register getter = inner_temporary_register_scope.NextConsecutiveRegister(); 1057 Register getter = register_allocator()->NextConsecutiveRegister();
1027 Register setter = inner_temporary_register_scope.NextConsecutiveRegister(); 1058 Register setter = register_allocator()->NextConsecutiveRegister();
1028 Register attr = inner_temporary_register_scope.NextConsecutiveRegister(); 1059 Register attr = register_allocator()->NextConsecutiveRegister();
1029 DCHECK(Register::AreContiguous(literal, name, getter, setter, attr)); 1060 DCHECK(Register::AreContiguous(literal, name, getter, setter, attr));
1030 VisitForAccumulatorValue(it->first); 1061 VisitForAccumulatorValue(it->first);
1031 builder()->StoreAccumulatorInRegister(name); 1062 builder()->StoreAccumulatorInRegister(name);
1032 VisitObjectLiteralAccessor(literal, it->second->getter, getter); 1063 VisitObjectLiteralAccessor(literal, it->second->getter, getter);
1033 VisitObjectLiteralAccessor(literal, it->second->setter, setter); 1064 VisitObjectLiteralAccessor(literal, it->second->setter, setter);
1034 builder() 1065 builder()
1035 ->LoadLiteral(Smi::FromInt(NONE)) 1066 ->LoadLiteral(Smi::FromInt(NONE))
1036 .StoreAccumulatorInRegister(attr) 1067 .StoreAccumulatorInRegister(attr)
1037 .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, literal, 5); 1068 .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, literal, 5);
1038 } 1069 }
1039 1070
1040 // Object literals have two parts. The "static" part on the left contains no 1071 // Object literals have two parts. The "static" part on the left contains no
1041 // computed property names, and so we can compute its map ahead of time; see 1072 // computed property names, and so we can compute its map ahead of time; see
1042 // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts 1073 // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
1043 // with the first computed property name and continues with all properties to 1074 // with the first computed property name and continues with all properties to
1044 // its right. All the code from above initializes the static component of the 1075 // its right. All the code from above initializes the static component of the
1045 // object literal, and arranges for the map of the result to reflect the 1076 // object literal, and arranges for the map of the result to reflect the
1046 // static order in which the keys appear. For the dynamic properties, we 1077 // static order in which the keys appear. For the dynamic properties, we
1047 // compile them into a series of "SetOwnProperty" runtime calls. This will 1078 // compile them into a series of "SetOwnProperty" runtime calls. This will
1048 // preserve insertion order. 1079 // preserve insertion order.
1049 for (; property_index < expr->properties()->length(); property_index++) { 1080 for (; property_index < expr->properties()->length(); property_index++) {
1050 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1051
1052 if (literal_in_accumulator) { 1081 if (literal_in_accumulator) {
1053 temporary_register_scope.PrepareForConsecutiveAllocations(4); 1082 literal = register_allocator()->NewRegister();
1054 literal = temporary_register_scope.NextConsecutiveRegister();
1055 builder()->StoreAccumulatorInRegister(literal); 1083 builder()->StoreAccumulatorInRegister(literal);
1056 literal_in_accumulator = false; 1084 literal_in_accumulator = false;
1057 } 1085 }
1058 1086
1087 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1088 RegisterAllocationScope inner_register_scope(this);
1059 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1089 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1060 DCHECK(property->emit_store()); 1090 DCHECK(property->emit_store());
1061 TemporaryRegisterScope inner_temporary_register_scope(builder()); 1091 Register value = register_allocator()->NewRegister();
1062 Register value = inner_temporary_register_scope.NewRegister();
1063 DCHECK(Register::AreContiguous(literal, value)); 1092 DCHECK(Register::AreContiguous(literal, value));
1064 VisitForAccumulatorValue(property->value()); 1093 VisitForAccumulatorValue(property->value());
1065 builder()->StoreAccumulatorInRegister(value).CallRuntime( 1094 builder()->StoreAccumulatorInRegister(value).CallRuntime(
1066 Runtime::kInternalSetPrototype, literal, 2); 1095 Runtime::kInternalSetPrototype, literal, 2);
1067 continue; 1096 continue;
1068 } 1097 }
1069 1098
1070 TemporaryRegisterScope inner_temporary_register_scope(builder()); 1099 register_allocator()->PrepareForConsecutiveAllocations(3);
1071 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3); 1100 Register key = register_allocator()->NextConsecutiveRegister();
1072 Register key = inner_temporary_register_scope.NextConsecutiveRegister(); 1101 Register value = register_allocator()->NextConsecutiveRegister();
1073 Register value = inner_temporary_register_scope.NextConsecutiveRegister(); 1102 Register attr = register_allocator()->NextConsecutiveRegister();
1074 Register attr = inner_temporary_register_scope.NextConsecutiveRegister();
1075 DCHECK(Register::AreContiguous(literal, key, value, attr)); 1103 DCHECK(Register::AreContiguous(literal, key, value, attr));
1076 1104
1077 VisitForAccumulatorValue(property->key()); 1105 VisitForAccumulatorValue(property->key());
1078 builder()->CastAccumulatorToName().StoreAccumulatorInRegister(key); 1106 builder()->CastAccumulatorToName().StoreAccumulatorInRegister(key);
1079 VisitForAccumulatorValue(property->value()); 1107 VisitForAccumulatorValue(property->value());
1080 builder()->StoreAccumulatorInRegister(value); 1108 builder()->StoreAccumulatorInRegister(value);
1081 VisitSetHomeObject(value, literal, property); 1109 VisitSetHomeObject(value, literal, property);
1082 builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr); 1110 builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr);
1083 Runtime::FunctionId function_id = static_cast<Runtime::FunctionId>(-1); 1111 Runtime::FunctionId function_id = static_cast<Runtime::FunctionId>(-1);
1084 switch (property->kind()) { 1112 switch (property->kind()) {
(...skipping 27 matching lines...) Expand all
1112 } 1140 }
1113 execution_result()->SetResultInAccumulator(); 1141 execution_result()->SetResultInAccumulator();
1114 } 1142 }
1115 1143
1116 1144
1117 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1145 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1118 // Deep-copy the literal boilerplate. 1146 // Deep-copy the literal boilerplate.
1119 builder()->CreateArrayLiteral(expr->constant_elements(), 1147 builder()->CreateArrayLiteral(expr->constant_elements(),
1120 expr->literal_index(), 1148 expr->literal_index(),
1121 expr->ComputeFlags(true)); 1149 expr->ComputeFlags(true));
1122
1123 TemporaryRegisterScope temporary_register_scope(builder());
1124 Register index, literal; 1150 Register index, literal;
1125 1151
1126 // Evaluate all the non-constant subexpressions and store them into the 1152 // Evaluate all the non-constant subexpressions and store them into the
1127 // newly cloned array. 1153 // newly cloned array.
1128 bool literal_in_accumulator = true; 1154 bool literal_in_accumulator = true;
1129 for (int array_index = 0; array_index < expr->values()->length(); 1155 for (int array_index = 0; array_index < expr->values()->length();
1130 array_index++) { 1156 array_index++) {
1131 Expression* subexpr = expr->values()->at(array_index); 1157 Expression* subexpr = expr->values()->at(array_index);
1132 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1158 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1133 if (subexpr->IsSpread()) { 1159 if (subexpr->IsSpread()) {
1134 // TODO(rmcilroy): Deal with spread expressions. 1160 // TODO(rmcilroy): Deal with spread expressions.
1135 UNIMPLEMENTED(); 1161 UNIMPLEMENTED();
1136 } 1162 }
1137 1163
1138 if (literal_in_accumulator) { 1164 if (literal_in_accumulator) {
1139 index = temporary_register_scope.NewRegister(); 1165 index = register_allocator()->NewRegister();
1140 literal = temporary_register_scope.NewRegister(); 1166 literal = register_allocator()->NewRegister();
1141 builder()->StoreAccumulatorInRegister(literal); 1167 builder()->StoreAccumulatorInRegister(literal);
1142 literal_in_accumulator = false; 1168 literal_in_accumulator = false;
1143 } 1169 }
1144 1170
1145 FeedbackVectorSlot slot = expr->LiteralFeedbackSlot(); 1171 FeedbackVectorSlot slot = expr->LiteralFeedbackSlot();
1146 builder() 1172 builder()
1147 ->LoadLiteral(Smi::FromInt(array_index)) 1173 ->LoadLiteral(Smi::FromInt(array_index))
1148 .StoreAccumulatorInRegister(index); 1174 .StoreAccumulatorInRegister(index);
1149 VisitForAccumulatorValue(subexpr); 1175 VisitForAccumulatorValue(subexpr);
1150 builder()->StoreKeyedProperty(literal, index, feedback_index(slot), 1176 builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 execution_result()->SetResultInAccumulator(); 1215 execution_result()->SetResultInAccumulator();
1190 break; 1216 break;
1191 } 1217 }
1192 case VariableLocation::CONTEXT: { 1218 case VariableLocation::CONTEXT: {
1193 int depth = execution_context()->ContextChainDepth(variable->scope()); 1219 int depth = execution_context()->ContextChainDepth(variable->scope());
1194 ContextScope* context = execution_context()->Previous(depth); 1220 ContextScope* context = execution_context()->Previous(depth);
1195 Register context_reg; 1221 Register context_reg;
1196 if (context) { 1222 if (context) {
1197 context_reg = context->reg(); 1223 context_reg = context->reg();
1198 } else { 1224 } else {
1199 context_reg = execution_result()->NewRegister(); 1225 context_reg = register_allocator()->NewRegister();
1200 // Walk the context chain to find the context at the given depth. 1226 // Walk the context chain to find the context at the given depth.
1201 // TODO(rmcilroy): Perform this work in a bytecode handler once we have 1227 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
1202 // a generic mechanism for performing jumps in interpreter.cc. 1228 // a generic mechanism for performing jumps in interpreter.cc.
1203 // TODO(mythria): Also update bytecode graph builder with correct depth 1229 // TODO(mythria): Also update bytecode graph builder with correct depth
1204 // when this changes. 1230 // when this changes.
1205 builder() 1231 builder()
1206 ->LoadAccumulatorWithRegister(execution_context()->reg()) 1232 ->LoadAccumulatorWithRegister(execution_context()->reg())
1207 .StoreAccumulatorInRegister(context_reg); 1233 .StoreAccumulatorInRegister(context_reg);
1208 for (int i = 0; i < depth; ++i) { 1234 for (int i = 0; i < depth; ++i) {
1209 builder() 1235 builder()
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 break; 1290 break;
1265 } 1291 }
1266 case VariableLocation::CONTEXT: { 1292 case VariableLocation::CONTEXT: {
1267 // TODO(rmcilroy): support const mode initialization. 1293 // TODO(rmcilroy): support const mode initialization.
1268 int depth = execution_context()->ContextChainDepth(variable->scope()); 1294 int depth = execution_context()->ContextChainDepth(variable->scope());
1269 ContextScope* context = execution_context()->Previous(depth); 1295 ContextScope* context = execution_context()->Previous(depth);
1270 Register context_reg; 1296 Register context_reg;
1271 if (context) { 1297 if (context) {
1272 context_reg = context->reg(); 1298 context_reg = context->reg();
1273 } else { 1299 } else {
1274 Register value_temp = execution_result()->NewRegister(); 1300 Register value_temp = register_allocator()->NewRegister();
1275 context_reg = execution_result()->NewRegister(); 1301 context_reg = register_allocator()->NewRegister();
1276 // Walk the context chain to find the context at the given depth. 1302 // Walk the context chain to find the context at the given depth.
1277 // TODO(rmcilroy): Perform this work in a bytecode handler once we have 1303 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
1278 // a generic mechanism for performing jumps in interpreter.cc. 1304 // a generic mechanism for performing jumps in interpreter.cc.
1279 // TODO(mythria): Also update bytecode graph builder with correct depth 1305 // TODO(mythria): Also update bytecode graph builder with correct depth
1280 // when this changes. 1306 // when this changes.
1281 builder() 1307 builder()
1282 ->StoreAccumulatorInRegister(value_temp) 1308 ->StoreAccumulatorInRegister(value_temp)
1283 .LoadAccumulatorWithRegister(execution_context()->reg()) 1309 .LoadAccumulatorWithRegister(execution_context()->reg())
1284 .StoreAccumulatorInRegister(context_reg); 1310 .StoreAccumulatorInRegister(context_reg);
1285 for (int i = 0; i < depth; ++i) { 1311 for (int i = 0; i < depth; ++i) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 case NAMED_PROPERTY: { 1343 case NAMED_PROPERTY: {
1318 object = VisitForRegisterValue(property->obj()); 1344 object = VisitForRegisterValue(property->obj());
1319 name = property->key()->AsLiteral()->AsPropertyName(); 1345 name = property->key()->AsLiteral()->AsPropertyName();
1320 break; 1346 break;
1321 } 1347 }
1322 case KEYED_PROPERTY: { 1348 case KEYED_PROPERTY: {
1323 object = VisitForRegisterValue(property->obj()); 1349 object = VisitForRegisterValue(property->obj());
1324 if (expr->is_compound()) { 1350 if (expr->is_compound()) {
1325 // Use VisitForAccumulator and store to register so that the key is 1351 // Use VisitForAccumulator and store to register so that the key is
1326 // still in the accumulator for loading the old value below. 1352 // still in the accumulator for loading the old value below.
1327 key = execution_result()->NewRegister(); 1353 key = register_allocator()->NewRegister();
1328 VisitForAccumulatorValue(property->key()); 1354 VisitForAccumulatorValue(property->key());
1329 builder()->StoreAccumulatorInRegister(key); 1355 builder()->StoreAccumulatorInRegister(key);
1330 } else { 1356 } else {
1331 key = VisitForRegisterValue(property->key()); 1357 key = VisitForRegisterValue(property->key());
1332 } 1358 }
1333 break; 1359 break;
1334 } 1360 }
1335 case NAMED_SUPER_PROPERTY: 1361 case NAMED_SUPER_PROPERTY:
1336 case KEYED_SUPER_PROPERTY: 1362 case KEYED_SUPER_PROPERTY:
1337 UNIMPLEMENTED(); 1363 UNIMPLEMENTED();
1338 } 1364 }
1339 1365
1340 // Evaluate the value and potentially handle compound assignments by loading 1366 // Evaluate the value and potentially handle compound assignments by loading
1341 // the left-hand side value and performing a binary operation. 1367 // the left-hand side value and performing a binary operation.
1342 if (expr->is_compound()) { 1368 if (expr->is_compound()) {
1343 Register old_value; 1369 Register old_value;
1344 switch (assign_type) { 1370 switch (assign_type) {
1345 case VARIABLE: { 1371 case VARIABLE: {
1346 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1372 VariableProxy* proxy = expr->target()->AsVariableProxy();
1347 old_value = VisitVariableLoadForRegisterValue( 1373 old_value = VisitVariableLoadForRegisterValue(
1348 proxy->var(), proxy->VariableFeedbackSlot()); 1374 proxy->var(), proxy->VariableFeedbackSlot());
1349 break; 1375 break;
1350 } 1376 }
1351 case NAMED_PROPERTY: { 1377 case NAMED_PROPERTY: {
1352 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 1378 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
1353 old_value = execution_result()->NewRegister(); 1379 old_value = register_allocator()->NewRegister();
1354 builder() 1380 builder()
1355 ->LoadNamedProperty(object, name, feedback_index(slot), 1381 ->LoadNamedProperty(object, name, feedback_index(slot),
1356 language_mode()) 1382 language_mode())
1357 .StoreAccumulatorInRegister(old_value); 1383 .StoreAccumulatorInRegister(old_value);
1358 break; 1384 break;
1359 } 1385 }
1360 case KEYED_PROPERTY: { 1386 case KEYED_PROPERTY: {
1361 // Key is already in accumulator at this point due to evaluating the 1387 // Key is already in accumulator at this point due to evaluating the
1362 // LHS above. 1388 // LHS above.
1363 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 1389 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
1364 old_value = execution_result()->NewRegister(); 1390 old_value = register_allocator()->NewRegister();
1365 builder() 1391 builder()
1366 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) 1392 ->LoadKeyedProperty(object, feedback_index(slot), language_mode())
1367 .StoreAccumulatorInRegister(old_value); 1393 .StoreAccumulatorInRegister(old_value);
1368 break; 1394 break;
1369 } 1395 }
1370 case NAMED_SUPER_PROPERTY: 1396 case NAMED_SUPER_PROPERTY:
1371 case KEYED_SUPER_PROPERTY: 1397 case KEYED_SUPER_PROPERTY:
1372 UNIMPLEMENTED(); 1398 UNIMPLEMENTED();
1373 break; 1399 break;
1374 } 1400 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 // Visit arguments and place in a contiguous block of temporary 1486 // Visit arguments and place in a contiguous block of temporary
1461 // registers. Return the first temporary register corresponding to 1487 // registers. Return the first temporary register corresponding to
1462 // the first argument. 1488 // the first argument.
1463 // 1489 //
1464 // NB the caller may have already called 1490 // NB the caller may have already called
1465 // PrepareForConsecutiveAllocations() with args->length() + N. The 1491 // PrepareForConsecutiveAllocations() with args->length() + N. The
1466 // second call here will be a no-op provided there have been N or 1492 // second call here will be a no-op provided there have been N or
1467 // less calls to NextConsecutiveRegister(). Otherwise, the arguments 1493 // less calls to NextConsecutiveRegister(). Otherwise, the arguments
1468 // here will be consecutive, but they will not be consecutive with 1494 // here will be consecutive, but they will not be consecutive with
1469 // earlier consecutive allocations made by the caller. 1495 // earlier consecutive allocations made by the caller.
1470 execution_result()->PrepareForConsecutiveAllocations(args->length()); 1496 register_allocator()->PrepareForConsecutiveAllocations(args->length());
1471 1497
1472 // Visit for first argument that goes into returned register 1498 // Visit for first argument that goes into returned register
1473 Register first_arg = execution_result()->NextConsecutiveRegister(); 1499 Register first_arg = register_allocator()->NextConsecutiveRegister();
1474 VisitForAccumulatorValue(args->at(0)); 1500 VisitForAccumulatorValue(args->at(0));
1475 builder()->StoreAccumulatorInRegister(first_arg); 1501 builder()->StoreAccumulatorInRegister(first_arg);
1476 1502
1477 // Visit remaining arguments 1503 // Visit remaining arguments
1478 for (int i = 1; i < static_cast<int>(args->length()); i++) { 1504 for (int i = 1; i < static_cast<int>(args->length()); i++) {
1479 Register ith_arg = execution_result()->NextConsecutiveRegister(); 1505 Register ith_arg = register_allocator()->NextConsecutiveRegister();
1480 VisitForAccumulatorValue(args->at(i)); 1506 VisitForAccumulatorValue(args->at(i));
1481 builder()->StoreAccumulatorInRegister(ith_arg); 1507 builder()->StoreAccumulatorInRegister(ith_arg);
1482 DCHECK(ith_arg.index() - i == first_arg.index()); 1508 DCHECK(ith_arg.index() - i == first_arg.index());
1483 } 1509 }
1484 return first_arg; 1510 return first_arg;
1485 } 1511 }
1486 1512
1487 1513
1488 void BytecodeGenerator::VisitCall(Call* expr) { 1514 void BytecodeGenerator::VisitCall(Call* expr) {
1489 Expression* callee_expr = expr->expression(); 1515 Expression* callee_expr = expr->expression();
1490 Call::CallType call_type = expr->GetCallType(isolate()); 1516 Call::CallType call_type = expr->GetCallType(isolate());
1491 1517
1492 // Prepare the callee and the receiver to the function call. This depends on 1518 // Prepare the callee and the receiver to the function call. This depends on
1493 // the semantics of the underlying call type. 1519 // the semantics of the underlying call type.
1494 1520
1495 // The receiver and arguments need to be allocated consecutively for 1521 // The receiver and arguments need to be allocated consecutively for
1496 // Call(). We allocate the callee and receiver consecutively for calls to 1522 // Call(). We allocate the callee and receiver consecutively for calls to
1497 // kLoadLookupSlot. Future optimizations could avoid this there are no 1523 // kLoadLookupSlot. Future optimizations could avoid this there are no
1498 // arguments or the receiver and arguments are already consecutive. 1524 // arguments or the receiver and arguments are already consecutive.
1499 ZoneList<Expression*>* args = expr->arguments(); 1525 ZoneList<Expression*>* args = expr->arguments();
1500 execution_result()->PrepareForConsecutiveAllocations(args->length() + 2); 1526 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2);
1501 Register callee = execution_result()->NextConsecutiveRegister(); 1527 Register callee = register_allocator()->NextConsecutiveRegister();
1502 Register receiver = execution_result()->NextConsecutiveRegister(); 1528 Register receiver = register_allocator()->NextConsecutiveRegister();
1503 1529
1504 switch (call_type) { 1530 switch (call_type) {
1505 case Call::NAMED_PROPERTY_CALL: 1531 case Call::NAMED_PROPERTY_CALL:
1506 case Call::KEYED_PROPERTY_CALL: { 1532 case Call::KEYED_PROPERTY_CALL: {
1507 Property* property = callee_expr->AsProperty(); 1533 Property* property = callee_expr->AsProperty();
1508 VisitForAccumulatorValue(property->obj()); 1534 VisitForAccumulatorValue(property->obj());
1509 builder()->StoreAccumulatorInRegister(receiver); 1535 builder()->StoreAccumulatorInRegister(receiver);
1510 VisitPropertyLoadForAccumulator(receiver, property); 1536 VisitPropertyLoadForAccumulator(receiver, property);
1511 builder()->StoreAccumulatorInRegister(callee); 1537 builder()->StoreAccumulatorInRegister(callee);
1512 break; 1538 break;
1513 } 1539 }
1514 case Call::GLOBAL_CALL: { 1540 case Call::GLOBAL_CALL: {
1515 // Receiver is undefined for global calls. 1541 // Receiver is undefined for global calls.
1516 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1542 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1517 // Load callee as a global variable. 1543 // Load callee as a global variable.
1518 VariableProxy* proxy = callee_expr->AsVariableProxy(); 1544 VariableProxy* proxy = callee_expr->AsVariableProxy();
1519 VisitVariableLoadForAccumulatorValue(proxy->var(), 1545 VisitVariableLoadForAccumulatorValue(proxy->var(),
1520 proxy->VariableFeedbackSlot()); 1546 proxy->VariableFeedbackSlot());
1521 builder()->StoreAccumulatorInRegister(callee); 1547 builder()->StoreAccumulatorInRegister(callee);
1522 break; 1548 break;
1523 } 1549 }
1524 case Call::LOOKUP_SLOT_CALL: 1550 case Call::LOOKUP_SLOT_CALL:
1525 case Call::POSSIBLY_EVAL_CALL: { 1551 case Call::POSSIBLY_EVAL_CALL: {
1526 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { 1552 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) {
1527 TemporaryRegisterScope temporary_register_scope(builder()); 1553 RegisterAllocationScope inner_register_scope(this);
1528 temporary_register_scope.PrepareForConsecutiveAllocations(2); 1554 register_allocator()->PrepareForConsecutiveAllocations(2);
1529 Register context = temporary_register_scope.NextConsecutiveRegister(); 1555 Register context = register_allocator()->NextConsecutiveRegister();
1530 Register name = temporary_register_scope.NextConsecutiveRegister(); 1556 Register name = register_allocator()->NextConsecutiveRegister();
1531 1557
1532 // Call LoadLookupSlot to get the callee and receiver. 1558 // Call LoadLookupSlot to get the callee and receiver.
1533 DCHECK(Register::AreContiguous(callee, receiver)); 1559 DCHECK(Register::AreContiguous(callee, receiver));
1534 Variable* variable = callee_expr->AsVariableProxy()->var(); 1560 Variable* variable = callee_expr->AsVariableProxy()->var();
1535 builder() 1561 builder()
1536 ->MoveRegister(Register::function_context(), context) 1562 ->MoveRegister(Register::function_context(), context)
1537 .LoadLiteral(variable->name()) 1563 .LoadLiteral(variable->name())
1538 .StoreAccumulatorInRegister(name) 1564 .StoreAccumulatorInRegister(name)
1539 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); 1565 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee);
1540 break; 1566 break;
(...skipping 14 matching lines...) Expand all
1555 } 1581 }
1556 1582
1557 // Evaluate all arguments to the function call and store in sequential 1583 // Evaluate all arguments to the function call and store in sequential
1558 // registers. 1584 // registers.
1559 Register arg = VisitArguments(args); 1585 Register arg = VisitArguments(args);
1560 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); 1586 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1);
1561 1587
1562 // Resolve callee for a potential direct eval call. This block will mutate the 1588 // Resolve callee for a potential direct eval call. This block will mutate the
1563 // callee value. 1589 // callee value.
1564 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { 1590 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) {
1565 TemporaryRegisterScope temporary_register_scope(builder()); 1591 RegisterAllocationScope inner_register_scope(this);
1566 temporary_register_scope.PrepareForConsecutiveAllocations(5); 1592 register_allocator()->PrepareForConsecutiveAllocations(5);
1567 Register callee_for_eval = 1593 Register callee_for_eval = register_allocator()->NextConsecutiveRegister();
1568 temporary_register_scope.NextConsecutiveRegister(); 1594 Register source = register_allocator()->NextConsecutiveRegister();
1569 Register source = temporary_register_scope.NextConsecutiveRegister(); 1595 Register function = register_allocator()->NextConsecutiveRegister();
1570 Register function = temporary_register_scope.NextConsecutiveRegister(); 1596 Register language = register_allocator()->NextConsecutiveRegister();
1571 Register language = temporary_register_scope.NextConsecutiveRegister(); 1597 Register position = register_allocator()->NextConsecutiveRegister();
1572 Register position = temporary_register_scope.NextConsecutiveRegister();
1573 1598
1574 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source 1599 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
1575 // strings and function closure, and loading language and 1600 // strings and function closure, and loading language and
1576 // position. 1601 // position.
1577 builder() 1602 builder()
1578 ->MoveRegister(callee, callee_for_eval) 1603 ->MoveRegister(callee, callee_for_eval)
1579 .MoveRegister(arg, source) 1604 .MoveRegister(arg, source)
1580 .MoveRegister(Register::function_closure(), function) 1605 .MoveRegister(Register::function_closure(), function)
1581 .LoadLiteral(Smi::FromInt(language_mode())) 1606 .LoadLiteral(Smi::FromInt(language_mode()))
1582 .StoreAccumulatorInRegister(language) 1607 .StoreAccumulatorInRegister(language)
1583 .LoadLiteral( 1608 .LoadLiteral(
1584 Smi::FromInt(execution_context()->scope()->start_position())) 1609 Smi::FromInt(execution_context()->scope()->start_position()))
1585 .StoreAccumulatorInRegister(position); 1610 .StoreAccumulatorInRegister(position);
1586 1611
1587 // Call ResolvePossiblyDirectEval and modify the callee. 1612 // Call ResolvePossiblyDirectEval and modify the callee.
1588 builder() 1613 builder()
1589 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) 1614 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5)
1590 .StoreAccumulatorInRegister(callee); 1615 .StoreAccumulatorInRegister(callee);
1591 } 1616 }
1592 1617
1593 // TODO(rmcilroy): Use CallIC to allow call type feedback. 1618 // TODO(rmcilroy): Use CallIC to allow call type feedback.
1594 builder()->Call(callee, receiver, args->length(), 1619 builder()->Call(callee, receiver, args->length(),
1595 feedback_index(expr->CallFeedbackICSlot())); 1620 feedback_index(expr->CallFeedbackICSlot()));
1596 execution_result()->SetResultInAccumulator(); 1621 execution_result()->SetResultInAccumulator();
1597 } 1622 }
1598 1623
1599 1624
1600 void BytecodeGenerator::VisitCallNew(CallNew* expr) { 1625 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
1601 Register constructor = execution_result()->NewRegister(); 1626 Register constructor = register_allocator()->NewRegister();
1602 VisitForAccumulatorValue(expr->expression()); 1627 VisitForAccumulatorValue(expr->expression());
1603 builder()->StoreAccumulatorInRegister(constructor); 1628 builder()->StoreAccumulatorInRegister(constructor);
1604 1629
1605 ZoneList<Expression*>* args = expr->arguments(); 1630 ZoneList<Expression*>* args = expr->arguments();
1606 Register first_arg = VisitArguments(args); 1631 Register first_arg = VisitArguments(args);
1607 builder()->New(constructor, first_arg, args->length()); 1632 builder()->New(constructor, first_arg, args->length());
1608 execution_result()->SetResultInAccumulator(); 1633 execution_result()->SetResultInAccumulator();
1609 } 1634 }
1610 1635
1611 1636
1612 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1637 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1613 ZoneList<Expression*>* args = expr->arguments(); 1638 ZoneList<Expression*>* args = expr->arguments();
1614 Register receiver; 1639 Register receiver;
1615 if (expr->is_jsruntime()) { 1640 if (expr->is_jsruntime()) {
1616 // Allocate a register for the receiver and load it with undefined. 1641 // Allocate a register for the receiver and load it with undefined.
1617 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); 1642 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 1);
1618 receiver = execution_result()->NextConsecutiveRegister(); 1643 receiver = register_allocator()->NextConsecutiveRegister();
1619 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1644 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1620 } 1645 }
1621 // Evaluate all arguments to the runtime call. 1646 // Evaluate all arguments to the runtime call.
1622 Register first_arg = VisitArguments(args); 1647 Register first_arg = VisitArguments(args);
1623 1648
1624 if (expr->is_jsruntime()) { 1649 if (expr->is_jsruntime()) {
1625 DCHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1); 1650 DCHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1);
1626 builder()->CallJSRuntime(expr->context_index(), receiver, args->length()); 1651 builder()->CallJSRuntime(expr->context_index(), receiver, args->length());
1627 } else { 1652 } else {
1628 Runtime::FunctionId function_id = expr->function()->function_id; 1653 Runtime::FunctionId function_id = expr->function()->function_id;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 } else if (expr->expression()->IsVariableProxy()) { 1723 } else if (expr->expression()->IsVariableProxy()) {
1699 // Delete of an unqualified identifier is allowed in sloppy mode but is 1724 // Delete of an unqualified identifier is allowed in sloppy mode but is
1700 // not allowed in strict mode. Deleting 'this' is allowed in both modes. 1725 // not allowed in strict mode. Deleting 'this' is allowed in both modes.
1701 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1726 VariableProxy* proxy = expr->expression()->AsVariableProxy();
1702 Variable* variable = proxy->var(); 1727 Variable* variable = proxy->var();
1703 DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate())); 1728 DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate()));
1704 switch (variable->location()) { 1729 switch (variable->location()) {
1705 case VariableLocation::GLOBAL: 1730 case VariableLocation::GLOBAL:
1706 case VariableLocation::UNALLOCATED: { 1731 case VariableLocation::UNALLOCATED: {
1707 // Global var, let, const or variables not explicitly declared. 1732 // Global var, let, const or variables not explicitly declared.
1708 Register native_context = execution_result()->NewRegister(); 1733 Register native_context = register_allocator()->NewRegister();
1709 Register global_object = execution_result()->NewRegister(); 1734 Register global_object = register_allocator()->NewRegister();
1710 builder() 1735 builder()
1711 ->LoadContextSlot(execution_context()->reg(), 1736 ->LoadContextSlot(execution_context()->reg(),
1712 Context::NATIVE_CONTEXT_INDEX) 1737 Context::NATIVE_CONTEXT_INDEX)
1713 .StoreAccumulatorInRegister(native_context) 1738 .StoreAccumulatorInRegister(native_context)
1714 .LoadContextSlot(native_context, Context::EXTENSION_INDEX) 1739 .LoadContextSlot(native_context, Context::EXTENSION_INDEX)
1715 .StoreAccumulatorInRegister(global_object) 1740 .StoreAccumulatorInRegister(global_object)
1716 .LoadLiteral(variable->name()) 1741 .LoadLiteral(variable->name())
1717 .Delete(global_object, language_mode()); 1742 .Delete(global_object, language_mode());
1718 break; 1743 break;
1719 } 1744 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 name = property->key()->AsLiteral()->AsPropertyName(); 1796 name = property->key()->AsLiteral()->AsPropertyName();
1772 builder()->LoadNamedProperty(obj, name, feedback_index(slot), 1797 builder()->LoadNamedProperty(obj, name, feedback_index(slot),
1773 language_mode()); 1798 language_mode());
1774 break; 1799 break;
1775 } 1800 }
1776 case KEYED_PROPERTY: { 1801 case KEYED_PROPERTY: {
1777 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 1802 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
1778 obj = VisitForRegisterValue(property->obj()); 1803 obj = VisitForRegisterValue(property->obj());
1779 // Use visit for accumulator here since we need the key in the accumulator 1804 // Use visit for accumulator here since we need the key in the accumulator
1780 // for the LoadKeyedProperty. 1805 // for the LoadKeyedProperty.
1781 key = execution_result()->NewRegister(); 1806 key = register_allocator()->NewRegister();
1782 VisitForAccumulatorValue(property->key()); 1807 VisitForAccumulatorValue(property->key());
1783 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( 1808 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
1784 obj, feedback_index(slot), language_mode()); 1809 obj, feedback_index(slot), language_mode());
1785 break; 1810 break;
1786 } 1811 }
1787 case NAMED_SUPER_PROPERTY: 1812 case NAMED_SUPER_PROPERTY:
1788 case KEYED_SUPER_PROPERTY: 1813 case KEYED_SUPER_PROPERTY:
1789 UNIMPLEMENTED(); 1814 UNIMPLEMENTED();
1790 } 1815 }
1791 1816
1792 // Convert old value into a number. 1817 // Convert old value into a number.
1793 if (!is_strong(language_mode())) { 1818 if (!is_strong(language_mode())) {
1794 builder()->CastAccumulatorToNumber(); 1819 builder()->CastAccumulatorToNumber();
1795 } 1820 }
1796 1821
1797 // Save result for postfix expressions. 1822 // Save result for postfix expressions.
1798 if (is_postfix) { 1823 if (is_postfix) {
1799 old_value = execution_result()->outer()->NewRegister(); 1824 old_value = register_allocator()->outer()->NewRegister();
1800 builder()->StoreAccumulatorInRegister(old_value); 1825 builder()->StoreAccumulatorInRegister(old_value);
1801 } 1826 }
1802 1827
1803 // Perform +1/-1 operation. 1828 // Perform +1/-1 operation.
1804 builder()->CountOperation(expr->binary_op(), language_mode_strength()); 1829 builder()->CountOperation(expr->binary_op(), language_mode_strength());
1805 1830
1806 // Store the value. 1831 // Store the value.
1807 FeedbackVectorSlot feedback_slot = expr->CountSlot(); 1832 FeedbackVectorSlot feedback_slot = expr->CountSlot();
1808 switch (assign_type) { 1833 switch (assign_type) {
1809 case VARIABLE: { 1834 case VARIABLE: {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 Visit(expr->expression()); 1967 Visit(expr->expression());
1943 } 1968 }
1944 1969
1945 1970
1946 void BytecodeGenerator::VisitNewLocalFunctionContext() { 1971 void BytecodeGenerator::VisitNewLocalFunctionContext() {
1947 AccumulatorResultScope accumulator_execution_result(this); 1972 AccumulatorResultScope accumulator_execution_result(this);
1948 Scope* scope = this->scope(); 1973 Scope* scope = this->scope();
1949 1974
1950 // Allocate a new local context. 1975 // Allocate a new local context.
1951 if (scope->is_script_scope()) { 1976 if (scope->is_script_scope()) {
1952 TemporaryRegisterScope temporary_register_scope(builder()); 1977 RegisterAllocationScope register_scope(this);
1953 Register closure = temporary_register_scope.NewRegister(); 1978 Register closure = register_allocator()->NewRegister();
1954 Register scope_info = temporary_register_scope.NewRegister(); 1979 Register scope_info = register_allocator()->NewRegister();
1955 DCHECK(Register::AreContiguous(closure, scope_info)); 1980 DCHECK(Register::AreContiguous(closure, scope_info));
1956 builder() 1981 builder()
1957 ->LoadAccumulatorWithRegister(Register::function_closure()) 1982 ->LoadAccumulatorWithRegister(Register::function_closure())
1958 .StoreAccumulatorInRegister(closure) 1983 .StoreAccumulatorInRegister(closure)
1959 .LoadLiteral(scope->GetScopeInfo(isolate())) 1984 .LoadLiteral(scope->GetScopeInfo(isolate()))
1960 .StoreAccumulatorInRegister(scope_info) 1985 .StoreAccumulatorInRegister(scope_info)
1961 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 1986 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
1962 } else { 1987 } else {
1963 builder()->CallRuntime(Runtime::kNewFunctionContext, 1988 builder()->CallRuntime(Runtime::kNewFunctionContext,
1964 Register::function_closure(), 1); 1989 Register::function_closure(), 1);
(...skipping 29 matching lines...) Expand all
1994 .StoreContextSlot(execution_context()->reg(), variable->index()); 2019 .StoreContextSlot(execution_context()->reg(), variable->index());
1995 } 2020 }
1996 } 2021 }
1997 2022
1998 2023
1999 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { 2024 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
2000 AccumulatorResultScope accumulator_execution_result(this); 2025 AccumulatorResultScope accumulator_execution_result(this);
2001 DCHECK(scope->is_block_scope()); 2026 DCHECK(scope->is_block_scope());
2002 2027
2003 // Allocate a new local block context. 2028 // Allocate a new local block context.
2004 TemporaryRegisterScope temporary_register_scope(builder()); 2029 register_allocator()->PrepareForConsecutiveAllocations(2);
2005 temporary_register_scope.PrepareForConsecutiveAllocations(2); 2030 Register scope_info = register_allocator()->NextConsecutiveRegister();
2006 Register scope_info = temporary_register_scope.NextConsecutiveRegister(); 2031 Register closure = register_allocator()->NextConsecutiveRegister();
2007 Register closure = temporary_register_scope.NextConsecutiveRegister();
2008 2032
2009 builder() 2033 builder()
2010 ->LoadLiteral(scope->GetScopeInfo(isolate())) 2034 ->LoadLiteral(scope->GetScopeInfo(isolate()))
2011 .StoreAccumulatorInRegister(scope_info); 2035 .StoreAccumulatorInRegister(scope_info);
2012 VisitFunctionClosureForContext(); 2036 VisitFunctionClosureForContext();
2013 builder() 2037 builder()
2014 ->StoreAccumulatorInRegister(closure) 2038 ->StoreAccumulatorInRegister(closure)
2015 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); 2039 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2);
2016 execution_result()->SetResultInAccumulator(); 2040 execution_result()->SetResultInAccumulator();
2017 } 2041 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 } 2101 }
2078 2102
2079 2103
2080 void BytecodeGenerator::VisitFunctionClosureForContext() { 2104 void BytecodeGenerator::VisitFunctionClosureForContext() {
2081 AccumulatorResultScope accumulator_execution_result(this); 2105 AccumulatorResultScope accumulator_execution_result(this);
2082 Scope* closure_scope = execution_context()->scope()->ClosureScope(); 2106 Scope* closure_scope = execution_context()->scope()->ClosureScope();
2083 if (closure_scope->is_script_scope() || 2107 if (closure_scope->is_script_scope() ||
2084 closure_scope->is_module_scope()) { 2108 closure_scope->is_module_scope()) {
2085 // Contexts nested in the native context have a canonical empty function as 2109 // Contexts nested in the native context have a canonical empty function as
2086 // their closure, not the anonymous closure containing the global code. 2110 // their closure, not the anonymous closure containing the global code.
2087 Register native_context = execution_result()->NewRegister(); 2111 Register native_context = register_allocator()->NewRegister();
2088 builder() 2112 builder()
2089 ->LoadContextSlot(execution_context()->reg(), 2113 ->LoadContextSlot(execution_context()->reg(),
2090 Context::NATIVE_CONTEXT_INDEX) 2114 Context::NATIVE_CONTEXT_INDEX)
2091 .StoreAccumulatorInRegister(native_context) 2115 .StoreAccumulatorInRegister(native_context)
2092 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); 2116 .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
2093 } else { 2117 } else {
2094 DCHECK(closure_scope->is_function_scope()); 2118 DCHECK(closure_scope->is_function_scope());
2095 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 2119 builder()->LoadAccumulatorWithRegister(Register::function_closure());
2096 } 2120 }
2097 execution_result()->SetResultInAccumulator(); 2121 execution_result()->SetResultInAccumulator();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2149 } 2173 }
2150 2174
2151 2175
2152 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2176 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2153 return info()->feedback_vector()->GetIndex(slot); 2177 return info()->feedback_vector()->GetIndex(slot);
2154 } 2178 }
2155 2179
2156 } // namespace interpreter 2180 } // namespace interpreter
2157 } // namespace internal 2181 } // namespace internal
2158 } // namespace v8 2182 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-register-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698