Chromium Code Reviews| 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/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 function_literals_(0, info->zone()), | 676 function_literals_(0, info->zone()), |
| 677 native_function_literals_(0, info->zone()), | 677 native_function_literals_(0, info->zone()), |
| 678 execution_control_(nullptr), | 678 execution_control_(nullptr), |
| 679 execution_context_(nullptr), | 679 execution_context_(nullptr), |
| 680 execution_result_(nullptr), | 680 execution_result_(nullptr), |
| 681 register_allocator_(nullptr), | 681 register_allocator_(nullptr), |
| 682 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 682 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
| 683 generator_state_(), | 683 generator_state_(), |
| 684 loop_depth_(0), | 684 loop_depth_(0), |
| 685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), | 685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
| 686 prototype_string_(info->isolate()->factory()->prototype_string()) { | 686 prototype_string_(info->isolate()->factory()->prototype_string()), |
| 687 } | 687 name_string_(info->isolate()->factory()->name_string()), |
| 688 empty_string_(info->isolate()->factory()->empty_string()) {} | |
|
Henrique Ferreiro
2016/10/17 11:41:11
Leftover from a preview version
| |
| 688 | 689 |
| 689 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 690 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
| 690 AllocateDeferredConstants(); | 691 AllocateDeferredConstants(); |
| 691 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 692 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
| 692 return builder()->ToBytecodeArray(isolate); | 693 return builder()->ToBytecodeArray(isolate); |
| 693 } | 694 } |
| 694 | 695 |
| 695 void BytecodeGenerator::AllocateDeferredConstants() { | 696 void BytecodeGenerator::AllocateDeferredConstants() { |
| 696 // Build global declaration pair arrays. | 697 // Build global declaration pair arrays. |
| 697 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 698 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
| (...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1486 register_allocator()->PrepareForConsecutiveAllocations(2); | 1487 register_allocator()->PrepareForConsecutiveAllocations(2); |
| 1487 Register literal = register_allocator()->NextConsecutiveRegister(); | 1488 Register literal = register_allocator()->NextConsecutiveRegister(); |
| 1488 Register prototype = register_allocator()->NextConsecutiveRegister(); | 1489 Register prototype = register_allocator()->NextConsecutiveRegister(); |
| 1489 FeedbackVectorSlot slot = expr->PrototypeSlot(); | 1490 FeedbackVectorSlot slot = expr->PrototypeSlot(); |
| 1490 builder() | 1491 builder() |
| 1491 ->StoreAccumulatorInRegister(literal) | 1492 ->StoreAccumulatorInRegister(literal) |
| 1492 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) | 1493 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) |
| 1493 .StoreAccumulatorInRegister(prototype); | 1494 .StoreAccumulatorInRegister(prototype); |
| 1494 | 1495 |
| 1495 VisitClassLiteralProperties(expr, literal, prototype); | 1496 VisitClassLiteralProperties(expr, literal, prototype); |
| 1497 | |
| 1498 VisitClassLiteralNameProperty(expr, literal); | |
| 1499 | |
| 1496 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); | 1500 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); |
| 1497 // Assign to class variable. | 1501 // Assign to class variable. |
| 1498 if (expr->class_variable_proxy() != nullptr) { | 1502 if (expr->class_variable_proxy() != nullptr) { |
| 1499 Variable* var = expr->class_variable_proxy()->var(); | 1503 Variable* var = expr->class_variable_proxy()->var(); |
| 1500 FeedbackVectorSlot slot = expr->NeedsProxySlot() | 1504 FeedbackVectorSlot slot = expr->NeedsProxySlot() |
| 1501 ? expr->ProxySlot() | 1505 ? expr->ProxySlot() |
| 1502 : FeedbackVectorSlot::Invalid(); | 1506 : FeedbackVectorSlot::Invalid(); |
| 1503 VisitVariableAssignment(var, Token::INIT, slot); | 1507 VisitVariableAssignment(var, Token::INIT, slot); |
| 1504 } | 1508 } |
| 1505 execution_result()->SetResultInAccumulator(); | 1509 execution_result()->SetResultInAccumulator(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1605 Register key) { | 1609 Register key) { |
| 1606 BytecodeLabel done; | 1610 BytecodeLabel done; |
| 1607 builder() | 1611 builder() |
| 1608 ->LoadLiteral(prototype_string()) | 1612 ->LoadLiteral(prototype_string()) |
| 1609 .CompareOperation(Token::Value::EQ_STRICT, key) | 1613 .CompareOperation(Token::Value::EQ_STRICT, key) |
| 1610 .JumpIfFalse(&done) | 1614 .JumpIfFalse(&done) |
| 1611 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) | 1615 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) |
| 1612 .Bind(&done); | 1616 .Bind(&done); |
| 1613 } | 1617 } |
| 1614 | 1618 |
| 1619 void BytecodeGenerator::VisitClassLiteralNameProperty(ClassLiteral* expr, | |
|
rmcilroy
2016/10/24 14:22:20
Nit - BuildClassLiteralNameProperty
| |
| 1620 Register literal) { | |
| 1621 DCHECK(!expr->constructor()->name().is_null()); | |
| 1622 | |
| 1623 // Abort if 'name' is undefined. | |
| 1624 // FIXME: fails many tests in a slow dcheck about dereferencing a handle | |
| 1625 if (expr->constructor()->name()->length() == 0) return; | |
|
Henrique Ferreiro
2016/10/17 11:41:11
Should I use a runtime function to check for this?
rmcilroy
2016/10/24 14:22:20
You could either do this in the runtime function I
caitp
2016/10/24 15:56:10
It looks like expr->class_variable_proxy() returns
Henrique Ferreiro
2016/11/08 22:28:58
I have moved everything to a runtime function. Is
caitp
2016/11/08 22:59:40
I'll defer to Ignition experts to answer that ---
rmcilroy
2016/11/10 12:37:44
A runtime call is just as expensive as it would be
Toon Verwaest
2016/11/24 07:16:23
This is exactly what I was referring to. Checking
| |
| 1626 | |
| 1627 BytecodeLabel end; | |
| 1628 | |
| 1629 RegisterAllocationScope register_scope(this); | |
| 1630 register_allocator()->PrepareForConsecutiveAllocations(5); | |
| 1631 Register receiver = register_allocator()->NextConsecutiveRegister(); | |
| 1632 Register key = register_allocator()->NextConsecutiveRegister(); | |
| 1633 Register value = register_allocator()->NextConsecutiveRegister(); | |
| 1634 Register attr = register_allocator()->NextConsecutiveRegister(); | |
| 1635 Register set_function_name = register_allocator()->NextConsecutiveRegister(); | |
| 1636 | |
| 1637 // If "name" is already defined, exit. | |
| 1638 builder() | |
| 1639 ->MoveRegister(literal, receiver) | |
| 1640 .LoadLiteral(name_string()) | |
| 1641 .StoreAccumulatorInRegister(key) | |
| 1642 .CallRuntime(Runtime::kObjectHasOwnProperty, receiver, 2) | |
| 1643 .JumpIfTrue(&end); | |
| 1644 | |
| 1645 // Define "name" property. | |
| 1646 builder() | |
| 1647 ->LoadLiteral(expr->constructor()->name()) | |
| 1648 .StoreAccumulatorInRegister(value) | |
| 1649 .LoadLiteral(Smi::FromInt(DONT_ENUM | READ_ONLY)) | |
| 1650 .StoreAccumulatorInRegister(attr) | |
| 1651 .LoadLiteral(Smi::FromInt(0)) | |
| 1652 .StoreAccumulatorInRegister(set_function_name) | |
| 1653 .CallRuntime(Runtime::kDefineDataPropertyInLiteral, receiver, 5); | |
|
rmcilroy
2016/10/24 14:22:20
Rather than creating a load of bytecode for this (
| |
| 1654 | |
| 1655 builder()->Bind(&end); | |
| 1656 } | |
| 1657 | |
| 1615 void BytecodeGenerator::VisitNativeFunctionLiteral( | 1658 void BytecodeGenerator::VisitNativeFunctionLiteral( |
| 1616 NativeFunctionLiteral* expr) { | 1659 NativeFunctionLiteral* expr) { |
| 1617 size_t entry = builder()->AllocateConstantPoolEntry(); | 1660 size_t entry = builder()->AllocateConstantPoolEntry(); |
| 1618 builder()->CreateClosure(entry, NOT_TENURED); | 1661 builder()->CreateClosure(entry, NOT_TENURED); |
| 1619 native_function_literals_.push_back(std::make_pair(expr, entry)); | 1662 native_function_literals_.push_back(std::make_pair(expr, entry)); |
| 1620 execution_result()->SetResultInAccumulator(); | 1663 execution_result()->SetResultInAccumulator(); |
| 1621 } | 1664 } |
| 1622 | 1665 |
| 1623 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { | 1666 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { |
| 1624 VisitBlock(expr->block()); | 1667 VisitBlock(expr->block()); |
| (...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3463 return execution_context()->scope()->language_mode(); | 3506 return execution_context()->scope()->language_mode(); |
| 3464 } | 3507 } |
| 3465 | 3508 |
| 3466 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3509 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3467 return TypeFeedbackVector::GetIndex(slot); | 3510 return TypeFeedbackVector::GetIndex(slot); |
| 3468 } | 3511 } |
| 3469 | 3512 |
| 3470 } // namespace interpreter | 3513 } // namespace interpreter |
| 3471 } // namespace internal | 3514 } // namespace internal |
| 3472 } // namespace v8 | 3515 } // namespace v8 |
| OLD | NEW |