| OLD | NEW |
| 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/bytecode-register-allocator.h" |
| 10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 } while (current != nullptr); | 366 } while (current != nullptr); |
| 367 UNREACHABLE(); | 367 UNREACHABLE(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 class BytecodeGenerator::RegisterAllocationScope { | 371 class BytecodeGenerator::RegisterAllocationScope { |
| 372 public: | 372 public: |
| 373 explicit RegisterAllocationScope(BytecodeGenerator* generator) | 373 explicit RegisterAllocationScope(BytecodeGenerator* generator) |
| 374 : generator_(generator), | 374 : generator_(generator), |
| 375 outer_(generator->register_allocator()), | 375 outer_(generator->register_allocator()), |
| 376 allocator_(builder()) { | 376 allocator_(builder()->zone(), |
| 377 builder()->temporary_register_allocator()) { |
| 377 generator_->set_register_allocator(this); | 378 generator_->set_register_allocator(this); |
| 378 } | 379 } |
| 379 | 380 |
| 380 virtual ~RegisterAllocationScope() { | 381 virtual ~RegisterAllocationScope() { |
| 381 generator_->set_register_allocator(outer_); | 382 generator_->set_register_allocator(outer_); |
| 382 } | 383 } |
| 383 | 384 |
| 384 Register NewRegister() { | 385 Register NewRegister() { |
| 385 RegisterAllocationScope* current_scope = generator()->register_allocator(); | 386 RegisterAllocationScope* current_scope = generator()->register_allocator(); |
| 386 if ((current_scope == this) || | 387 if ((current_scope == this) || |
| 387 (current_scope->outer() == this && | 388 (current_scope->outer() == this && |
| 388 !current_scope->allocator_.HasConsecutiveAllocations())) { | 389 !current_scope->allocator_.HasConsecutiveAllocations())) { |
| 389 // Regular case - Allocating registers in current or outer context. | 390 // Regular case - Allocating registers in current or outer context. |
| 390 // VisitForRegisterValue allocates register in outer context. | 391 // VisitForRegisterValue allocates register in outer context. |
| 391 return allocator_.NewRegister(); | 392 return allocator_.NewRegister(); |
| 392 } else { | 393 } else { |
| 393 // If it is required to allocate a register other than current or outer | 394 // If it is required to allocate a register other than current or outer |
| 394 // scopes, allocate a new temporary register. It might be expensive to | 395 // scopes, allocate a new temporary register. It might be expensive to |
| 395 // walk the full context chain and compute the list of consecutive | 396 // walk the full context chain and compute the list of consecutive |
| 396 // reservations in the innerscopes. | 397 // reservations in the innerscopes. |
| 397 UNIMPLEMENTED(); | 398 UNIMPLEMENTED(); |
| 398 return Register(-1); | 399 return Register::invalid_value(); |
| 399 } | 400 } |
| 400 } | 401 } |
| 401 | 402 |
| 402 void PrepareForConsecutiveAllocations(size_t count) { | 403 void PrepareForConsecutiveAllocations(int count) { |
| 403 allocator_.PrepareForConsecutiveAllocations(count); | 404 allocator_.PrepareForConsecutiveAllocations(count); |
| 404 } | 405 } |
| 405 | 406 |
| 406 Register NextConsecutiveRegister() { | 407 Register NextConsecutiveRegister() { |
| 407 return allocator_.NextConsecutiveRegister(); | 408 return allocator_.NextConsecutiveRegister(); |
| 408 } | 409 } |
| 409 | 410 |
| 410 bool RegisterIsAllocatedInThisScope(Register reg) const { | 411 bool RegisterIsAllocatedInThisScope(Register reg) const { |
| 411 return allocator_.RegisterIsAllocatedInThisScope(reg); | 412 return allocator_.RegisterIsAllocatedInThisScope(reg); |
| 412 } | 413 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 : ExpressionResultScope(generator, Expression::kValue) {} | 514 : ExpressionResultScope(generator, Expression::kValue) {} |
| 514 | 515 |
| 515 virtual void SetResultInAccumulator() { | 516 virtual void SetResultInAccumulator() { |
| 516 result_register_ = allocator()->outer()->NewRegister(); | 517 result_register_ = allocator()->outer()->NewRegister(); |
| 517 builder()->StoreAccumulatorInRegister(result_register_); | 518 builder()->StoreAccumulatorInRegister(result_register_); |
| 518 set_result_identified(); | 519 set_result_identified(); |
| 519 } | 520 } |
| 520 | 521 |
| 521 virtual void SetResultInRegister(Register reg) { | 522 virtual void SetResultInRegister(Register reg) { |
| 522 DCHECK(builder()->RegisterIsParameterOrLocal(reg) || | 523 DCHECK(builder()->RegisterIsParameterOrLocal(reg) || |
| 523 (builder()->RegisterIsTemporary(reg) && | 524 (builder()->TemporaryRegisterIsLive(reg) && |
| 524 !allocator()->RegisterIsAllocatedInThisScope(reg))); | 525 !allocator()->RegisterIsAllocatedInThisScope(reg))); |
| 525 result_register_ = reg; | 526 result_register_ = reg; |
| 526 set_result_identified(); | 527 set_result_identified(); |
| 527 } | 528 } |
| 528 | 529 |
| 529 Register ResultRegister() const { return result_register_; } | 530 Register ResultRegister() const { return result_register_; } |
| 530 | 531 |
| 531 private: | 532 private: |
| 532 Register result_register_; | 533 Register result_register_; |
| 533 }; | 534 }; |
| 534 | 535 |
| 535 | |
| 536 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) | 536 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) |
| 537 : isolate_(isolate), | 537 : isolate_(isolate), |
| 538 zone_(zone), | 538 zone_(zone), |
| 539 builder_(isolate, zone), | 539 builder_(nullptr), |
| 540 info_(nullptr), | 540 info_(nullptr), |
| 541 scope_(nullptr), | 541 scope_(nullptr), |
| 542 globals_(0, zone), | 542 globals_(0, zone), |
| 543 execution_control_(nullptr), | 543 execution_control_(nullptr), |
| 544 execution_context_(nullptr), | 544 execution_context_(nullptr), |
| 545 execution_result_(nullptr), | 545 execution_result_(nullptr), |
| 546 register_allocator_(nullptr) { | 546 register_allocator_(nullptr) { |
| 547 InitializeAstVisitor(isolate); | 547 InitializeAstVisitor(isolate); |
| 548 } | 548 } |
| 549 | 549 |
| 550 | 550 |
| 551 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { | 551 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { |
| 552 set_info(info); | 552 set_info(info); |
| 553 set_scope(info->scope()); | 553 set_scope(info->scope()); |
| 554 | 554 |
| 555 // Initialize bytecode array builder. |
| 556 set_builder(new (zone()) BytecodeArrayBuilder( |
| 557 isolate(), zone(), info->num_parameters_including_this(), |
| 558 scope()->MaxNestedContextChainLength(), scope()->num_stack_slots())); |
| 559 |
| 555 // Initialize the incoming context. | 560 // Initialize the incoming context. |
| 556 ContextScope incoming_context(this, scope(), false); | 561 ContextScope incoming_context(this, scope(), false); |
| 557 | 562 |
| 558 // Initialize control scope. | 563 // Initialize control scope. |
| 559 ControlScopeForTopLevel control(this); | 564 ControlScopeForTopLevel control(this); |
| 560 | 565 |
| 561 builder()->set_parameter_count(info->num_parameters_including_this()); | |
| 562 builder()->set_locals_count(scope()->num_stack_slots()); | |
| 563 builder()->set_context_count(scope()->MaxNestedContextChainLength()); | |
| 564 | |
| 565 // Build function context only if there are context allocated variables. | 566 // Build function context only if there are context allocated variables. |
| 566 if (scope()->NeedsContext()) { | 567 if (scope()->NeedsContext()) { |
| 567 // Push a new inner context scope for the function. | 568 // Push a new inner context scope for the function. |
| 568 VisitNewLocalFunctionContext(); | 569 VisitNewLocalFunctionContext(); |
| 569 ContextScope local_function_context(this, scope(), false); | 570 ContextScope local_function_context(this, scope(), false); |
| 570 VisitBuildLocalActivationContext(); | 571 VisitBuildLocalActivationContext(); |
| 571 MakeBytecodeBody(); | 572 MakeBytecodeBody(); |
| 572 } else { | 573 } else { |
| 573 MakeBytecodeBody(); | 574 MakeBytecodeBody(); |
| 574 } | 575 } |
| 575 | 576 |
| 576 set_scope(nullptr); | 577 set_scope(nullptr); |
| 577 set_info(nullptr); | 578 set_info(nullptr); |
| 578 return builder_.ToBytecodeArray(); | 579 return builder()->ToBytecodeArray(); |
| 579 } | 580 } |
| 580 | 581 |
| 581 | 582 |
| 582 void BytecodeGenerator::MakeBytecodeBody() { | 583 void BytecodeGenerator::MakeBytecodeBody() { |
| 583 // Build the arguments object if it is used. | 584 // Build the arguments object if it is used. |
| 584 VisitArgumentsObject(scope()->arguments()); | 585 VisitArgumentsObject(scope()->arguments()); |
| 585 | 586 |
| 586 // TODO(mythria): Build rest arguments array if it is used. | 587 // TODO(mythria): Build rest arguments array if it is used. |
| 587 int rest_index; | 588 int rest_index; |
| 588 if (scope()->rest_parameter(&rest_index)) { | 589 if (scope()->rest_parameter(&rest_index)) { |
| (...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2506 } | 2507 } |
| 2507 | 2508 |
| 2508 | 2509 |
| 2509 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2510 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2510 return info()->feedback_vector()->GetIndex(slot); | 2511 return info()->feedback_vector()->GetIndex(slot); |
| 2511 } | 2512 } |
| 2512 | 2513 |
| 2513 } // namespace interpreter | 2514 } // namespace interpreter |
| 2514 } // namespace internal | 2515 } // namespace internal |
| 2515 } // namespace v8 | 2516 } // namespace v8 |
| OLD | NEW |