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/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
10 #include "src/base/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 void MergeControlToEnd(JSGraph* jsgraph, Node* node) { | 59 void MergeControlToEnd(JSGraph* jsgraph, Node* node) { |
60 Graph* g = jsgraph->graph(); | 60 Graph* g = jsgraph->graph(); |
61 if (g->end()) { | 61 if (g->end()) { |
62 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node); | 62 NodeProperties::MergeControlToEnd(g, jsgraph->common(), node); |
63 } else { | 63 } else { |
64 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node)); | 64 g->SetEnd(g->NewNode(jsgraph->common()->End(1), node)); |
65 } | 65 } |
66 } | 66 } |
67 | 67 |
68 Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph, | 68 Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph, |
69 Node** effect_ptr, Node* control) { | 69 Node* centry_stub_node, Node** effect_ptr, |
| 70 Node* control) { |
70 // TODO(eholk): generate code to modify the thread-local storage directly, | 71 // TODO(eholk): generate code to modify the thread-local storage directly, |
71 // rather than calling the runtime. | 72 // rather than calling the runtime. |
72 if (!trap_handler::UseTrapHandler()) { | 73 if (!trap_handler::UseTrapHandler()) { |
73 return control; | 74 return control; |
74 } | 75 } |
75 | 76 |
76 const Runtime::FunctionId f = | 77 const Runtime::FunctionId f = |
77 new_value ? Runtime::kSetThreadInWasm : Runtime::kClearThreadInWasm; | 78 new_value ? Runtime::kSetThreadInWasm : Runtime::kClearThreadInWasm; |
78 const Runtime::Function* fun = Runtime::FunctionForId(f); | 79 const Runtime::Function* fun = Runtime::FunctionForId(f); |
79 DCHECK_EQ(0, fun->nargs); | 80 DCHECK_EQ(0, fun->nargs); |
80 const CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | 81 const CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( |
81 jsgraph->zone(), f, fun->nargs, Operator::kNoProperties, | 82 jsgraph->zone(), f, fun->nargs, Operator::kNoProperties, |
82 CallDescriptor::kNoFlags); | 83 CallDescriptor::kNoFlags); |
83 // CEntryStubConstant nodes have to be created and cached in the main | 84 // CEntryStubConstant nodes have to be created and cached in the main |
84 // thread. At the moment this is only done for CEntryStubConstant(1). | 85 // thread. At the moment this is only done for CEntryStubConstant(1). |
85 DCHECK_EQ(1, fun->result_size); | 86 DCHECK_EQ(1, fun->result_size); |
86 Node* inputs[] = {jsgraph->CEntryStubConstant(fun->result_size), | 87 Node* inputs[] = {centry_stub_node, |
87 jsgraph->ExternalConstant( | 88 jsgraph->ExternalConstant( |
88 ExternalReference(f, jsgraph->isolate())), // ref | 89 ExternalReference(f, jsgraph->isolate())), // ref |
89 jsgraph->Int32Constant(fun->nargs), // arity | 90 jsgraph->Int32Constant(fun->nargs), // arity |
90 jsgraph->NoContextConstant(), | 91 jsgraph->NoContextConstant(), |
91 *effect_ptr, | 92 *effect_ptr, |
92 control}; | 93 control}; |
93 | 94 |
94 Node* node = jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), | 95 Node* node = jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), |
95 arraysize(inputs), inputs); | 96 arraysize(inputs), inputs); |
96 *effect_ptr = node; | 97 *effect_ptr = node; |
97 return node; | 98 return node; |
98 } | 99 } |
99 | 100 |
100 // Only call this function for code which is not reused across instantiations, | 101 // Only call this function for code which is not reused across instantiations, |
101 // as we do not patch the embedded context. | 102 // as we do not patch the embedded context. |
102 Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph, | 103 Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph, |
103 Node* context, Node** parameters, | 104 Node* centry_stub_node, Node* context, |
104 int parameter_count, Node** effect_ptr, | 105 Node** parameters, int parameter_count, |
105 Node** control) { | 106 Node** effect_ptr, Node** control) { |
106 // Setting and clearing the thread-in-wasm flag should not be done as a normal | 107 // Setting and clearing the thread-in-wasm flag should not be done as a normal |
107 // runtime call. | 108 // runtime call. |
108 DCHECK_NE(f, Runtime::kSetThreadInWasm); | 109 DCHECK_NE(f, Runtime::kSetThreadInWasm); |
109 DCHECK_NE(f, Runtime::kClearThreadInWasm); | 110 DCHECK_NE(f, Runtime::kClearThreadInWasm); |
110 // We're leaving Wasm code, so clear the flag. | 111 // We're leaving Wasm code, so clear the flag. |
111 *control = BuildModifyThreadInWasmFlag(false, jsgraph, effect_ptr, *control); | 112 *control = BuildModifyThreadInWasmFlag(false, jsgraph, centry_stub_node, |
| 113 effect_ptr, *control); |
112 | 114 |
113 const Runtime::Function* fun = Runtime::FunctionForId(f); | 115 const Runtime::Function* fun = Runtime::FunctionForId(f); |
114 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | 116 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( |
115 jsgraph->zone(), f, fun->nargs, Operator::kNoProperties, | 117 jsgraph->zone(), f, fun->nargs, Operator::kNoProperties, |
116 CallDescriptor::kNoFlags); | 118 CallDescriptor::kNoFlags); |
117 // CEntryStubConstant nodes have to be created and cached in the main | 119 // CEntryStubConstant nodes have to be created and cached in the main |
118 // thread. At the moment this is only done for CEntryStubConstant(1). | 120 // thread. At the moment this is only done for CEntryStubConstant(1). |
119 DCHECK_EQ(1, fun->result_size); | 121 DCHECK_EQ(1, fun->result_size); |
120 // At the moment we only allow 3 parameters. If more parameters are needed, | 122 // At the moment we only allow 3 parameters. If more parameters are needed, |
121 // increase this constant accordingly. | 123 // increase this constant accordingly. |
122 static const int kMaxParams = 3; | 124 static const int kMaxParams = 3; |
123 DCHECK_GE(kMaxParams, parameter_count); | 125 DCHECK_GE(kMaxParams, parameter_count); |
124 Node* inputs[kMaxParams + 6]; | 126 Node* inputs[kMaxParams + 6]; |
125 int count = 0; | 127 int count = 0; |
126 inputs[count++] = jsgraph->CEntryStubConstant(fun->result_size); | 128 inputs[count++] = centry_stub_node; |
127 for (int i = 0; i < parameter_count; i++) { | 129 for (int i = 0; i < parameter_count; i++) { |
128 inputs[count++] = parameters[i]; | 130 inputs[count++] = parameters[i]; |
129 } | 131 } |
130 inputs[count++] = jsgraph->ExternalConstant( | 132 inputs[count++] = jsgraph->ExternalConstant( |
131 ExternalReference(f, jsgraph->isolate())); // ref | 133 ExternalReference(f, jsgraph->isolate())); // ref |
132 inputs[count++] = jsgraph->Int32Constant(fun->nargs); // arity | 134 inputs[count++] = jsgraph->Int32Constant(fun->nargs); // arity |
133 inputs[count++] = context; // context | 135 inputs[count++] = context; // context |
134 inputs[count++] = *effect_ptr; | 136 inputs[count++] = *effect_ptr; |
135 inputs[count++] = *control; | 137 inputs[count++] = *control; |
136 | 138 |
137 Node* node = | 139 Node* node = |
138 jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs); | 140 jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs); |
139 *effect_ptr = node; | 141 *effect_ptr = node; |
140 | 142 |
141 // Restore the thread-in-wasm flag, since we have returned to Wasm. | 143 // Restore the thread-in-wasm flag, since we have returned to Wasm. |
142 *control = BuildModifyThreadInWasmFlag(true, jsgraph, effect_ptr, *control); | 144 *control = BuildModifyThreadInWasmFlag(true, jsgraph, centry_stub_node, |
| 145 effect_ptr, *control); |
143 | 146 |
144 return node; | 147 return node; |
145 } | 148 } |
146 | 149 |
147 Node* BuildCallToRuntime(Runtime::FunctionId f, JSGraph* jsgraph, | 150 Node* BuildCallToRuntime(Runtime::FunctionId f, JSGraph* jsgraph, |
148 Node** parameters, int parameter_count, | 151 Node* centry_stub_node, Node** parameters, |
149 Node** effect_ptr, Node** control) { | 152 int parameter_count, Node** effect_ptr, |
150 return BuildCallToRuntimeWithContext(f, jsgraph, jsgraph->NoContextConstant(), | 153 Node** control) { |
151 parameters, parameter_count, effect_ptr, | 154 return BuildCallToRuntimeWithContext(f, jsgraph, centry_stub_node, |
152 control); | 155 jsgraph->NoContextConstant(), parameters, |
| 156 parameter_count, effect_ptr, control); |
153 } | 157 } |
154 | 158 |
155 } // namespace | 159 } // namespace |
156 | 160 |
157 WasmGraphBuilder::WasmGraphBuilder( | 161 WasmGraphBuilder::WasmGraphBuilder( |
158 wasm::ModuleEnv* module_env, Zone* zone, JSGraph* jsgraph, | 162 wasm::ModuleEnv* module_env, Zone* zone, JSGraph* jsgraph, |
159 wasm::FunctionSig* sig, | 163 Handle<Code> centry_stub, wasm::FunctionSig* sig, |
160 compiler::SourcePositionTable* source_position_table) | 164 compiler::SourcePositionTable* source_position_table) |
161 : zone_(zone), | 165 : zone_(zone), |
162 jsgraph_(jsgraph), | 166 jsgraph_(jsgraph), |
| 167 centry_stub_node_(jsgraph_->HeapConstant(centry_stub)), |
163 module_(module_env), | 168 module_(module_env), |
164 signature_tables_(zone), | 169 signature_tables_(zone), |
165 function_tables_(zone), | 170 function_tables_(zone), |
166 function_table_sizes_(zone), | 171 function_table_sizes_(zone), |
167 cur_buffer_(def_buffer_), | 172 cur_buffer_(def_buffer_), |
168 cur_bufsize_(kDefaultBufferSize), | 173 cur_bufsize_(kDefaultBufferSize), |
169 sig_(sig), | 174 sig_(sig), |
170 source_position_table_(source_position_table) { | 175 source_position_table_(source_position_table) { |
171 for (size_t i = sig->parameter_count(); i > 0 && !has_simd_; --i) { | 176 for (size_t i = sig->parameter_count(); i > 0 && !has_simd_; --i) { |
172 if (sig->GetParam(i - 1) == wasm::kWasmS128) has_simd_ = true; | 177 if (sig->GetParam(i - 1) == wasm::kWasmS128) has_simd_ = true; |
(...skipping 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 Diamond check_input_range( | 1719 Diamond check_input_range( |
1715 graph(), jsgraph()->common(), | 1720 graph(), jsgraph()->common(), |
1716 graph()->NewNode(jsgraph()->machine()->Uint32LessThanOrEqual(), input, | 1721 graph()->NewNode(jsgraph()->machine()->Uint32LessThanOrEqual(), input, |
1717 jsgraph()->Uint32Constant(FLAG_wasm_max_mem_pages)), | 1722 jsgraph()->Uint32Constant(FLAG_wasm_max_mem_pages)), |
1718 BranchHint::kTrue); | 1723 BranchHint::kTrue); |
1719 | 1724 |
1720 check_input_range.Chain(*control_); | 1725 check_input_range.Chain(*control_); |
1721 | 1726 |
1722 Node* parameters[] = {BuildChangeUint32ToSmi(input)}; | 1727 Node* parameters[] = {BuildChangeUint32ToSmi(input)}; |
1723 Node* old_effect = *effect_; | 1728 Node* old_effect = *effect_; |
1724 Node* call = BuildCallToRuntime(Runtime::kWasmGrowMemory, jsgraph(), | 1729 Node* call = BuildCallToRuntime( |
1725 parameters, arraysize(parameters), effect_, | 1730 Runtime::kWasmGrowMemory, jsgraph(), centry_stub_node_, parameters, |
1726 &check_input_range.if_true); | 1731 arraysize(parameters), effect_, &check_input_range.if_true); |
1727 | 1732 |
1728 Node* result = BuildChangeSmiToInt32(call); | 1733 Node* result = BuildChangeSmiToInt32(call); |
1729 | 1734 |
1730 result = check_input_range.Phi(MachineRepresentation::kWord32, result, | 1735 result = check_input_range.Phi(MachineRepresentation::kWord32, result, |
1731 jsgraph()->Int32Constant(-1)); | 1736 jsgraph()->Int32Constant(-1)); |
1732 *effect_ = graph()->NewNode(jsgraph()->common()->EffectPhi(2), *effect_, | 1737 *effect_ = graph()->NewNode(jsgraph()->common()->EffectPhi(2), *effect_, |
1733 old_effect, check_input_range.merge); | 1738 old_effect, check_input_range.merge); |
1734 *control_ = check_input_range.merge; | 1739 *control_ = check_input_range.merge; |
1735 return result; | 1740 return result; |
1736 } | 1741 } |
1737 | 1742 |
1738 Node* WasmGraphBuilder::Throw(Node* input) { | 1743 Node* WasmGraphBuilder::Throw(Node* input) { |
1739 MachineOperatorBuilder* machine = jsgraph()->machine(); | 1744 MachineOperatorBuilder* machine = jsgraph()->machine(); |
1740 | 1745 |
1741 // Pass the thrown value as two SMIs: | 1746 // Pass the thrown value as two SMIs: |
1742 // | 1747 // |
1743 // upper = static_cast<uint32_t>(input) >> 16; | 1748 // upper = static_cast<uint32_t>(input) >> 16; |
1744 // lower = input & 0xFFFF; | 1749 // lower = input & 0xFFFF; |
1745 // | 1750 // |
1746 // This is needed because we can't safely call BuildChangeInt32ToTagged from | 1751 // This is needed because we can't safely call BuildChangeInt32ToTagged from |
1747 // this method. | 1752 // this method. |
1748 // | 1753 // |
1749 // TODO(wasm): figure out how to properly pass this to the runtime function. | 1754 // TODO(wasm): figure out how to properly pass this to the runtime function. |
1750 Node* upper = BuildChangeInt32ToSmi( | 1755 Node* upper = BuildChangeInt32ToSmi( |
1751 graph()->NewNode(machine->Word32Shr(), input, Int32Constant(16))); | 1756 graph()->NewNode(machine->Word32Shr(), input, Int32Constant(16))); |
1752 Node* lower = BuildChangeInt32ToSmi( | 1757 Node* lower = BuildChangeInt32ToSmi( |
1753 graph()->NewNode(machine->Word32And(), input, Int32Constant(0xFFFFu))); | 1758 graph()->NewNode(machine->Word32And(), input, Int32Constant(0xFFFFu))); |
1754 | 1759 |
1755 Node* parameters[] = {lower, upper}; // thrown value | 1760 Node* parameters[] = {lower, upper}; // thrown value |
1756 return BuildCallToRuntime(Runtime::kWasmThrow, jsgraph(), parameters, | 1761 return BuildCallToRuntime(Runtime::kWasmThrow, jsgraph(), centry_stub_node_, |
1757 arraysize(parameters), effect_, control_); | 1762 parameters, arraysize(parameters), effect_, |
| 1763 control_); |
1758 } | 1764 } |
1759 | 1765 |
1760 Node* WasmGraphBuilder::Catch(Node* input, wasm::WasmCodePosition position) { | 1766 Node* WasmGraphBuilder::Catch(Node* input, wasm::WasmCodePosition position) { |
1761 CommonOperatorBuilder* common = jsgraph()->common(); | 1767 CommonOperatorBuilder* common = jsgraph()->common(); |
1762 | 1768 |
1763 Node* parameters[] = {input}; // caught value | 1769 Node* parameters[] = {input}; // caught value |
1764 Node* value = | 1770 Node* value = BuildCallToRuntime(Runtime::kWasmGetCaughtExceptionValue, |
1765 BuildCallToRuntime(Runtime::kWasmGetCaughtExceptionValue, jsgraph(), | 1771 jsgraph(), centry_stub_node_, parameters, |
1766 parameters, arraysize(parameters), effect_, control_); | 1772 arraysize(parameters), effect_, control_); |
1767 | 1773 |
1768 Node* is_smi; | 1774 Node* is_smi; |
1769 Node* is_heap; | 1775 Node* is_heap; |
1770 BranchExpectFalse(BuildTestNotSmi(value), &is_heap, &is_smi); | 1776 BranchExpectFalse(BuildTestNotSmi(value), &is_heap, &is_smi); |
1771 | 1777 |
1772 // is_smi | 1778 // is_smi |
1773 Node* smi_i32 = BuildChangeSmiToInt32(value); | 1779 Node* smi_i32 = BuildChangeSmiToInt32(value); |
1774 Node* is_smi_effect = *effect_; | 1780 Node* is_smi_effect = *effect_; |
1775 | 1781 |
1776 // is_heap | 1782 // is_heap |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2606 *control_ = start; | 2612 *control_ = start; |
2607 *effect_ = start; | 2613 *effect_ = start; |
2608 | 2614 |
2609 // Create the context parameter | 2615 // Create the context parameter |
2610 Node* context = graph()->NewNode( | 2616 Node* context = graph()->NewNode( |
2611 jsgraph()->common()->Parameter( | 2617 jsgraph()->common()->Parameter( |
2612 Linkage::GetJSCallContextParamIndex(wasm_count + 1), "%context"), | 2618 Linkage::GetJSCallContextParamIndex(wasm_count + 1), "%context"), |
2613 graph()->start()); | 2619 graph()->start()); |
2614 | 2620 |
2615 // Set the ThreadInWasm flag before we do the actual call. | 2621 // Set the ThreadInWasm flag before we do the actual call. |
2616 BuildModifyThreadInWasmFlag(true, jsgraph(), effect_, *control_); | 2622 BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_, |
| 2623 *control_); |
2617 | 2624 |
2618 if (!wasm::IsJSCompatibleSignature(sig_)) { | 2625 if (!wasm::IsJSCompatibleSignature(sig_)) { |
2619 // Throw a TypeError. Use the context of the calling javascript function | 2626 // Throw a TypeError. Use the context of the calling javascript function |
2620 // (passed as a parameter), such that the generated code is context | 2627 // (passed as a parameter), such that the generated code is context |
2621 // independent. | 2628 // independent. |
2622 BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), | 2629 BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), |
2623 context, nullptr, 0, effect_, control_); | 2630 centry_stub_node_, context, nullptr, 0, |
| 2631 effect_, control_); |
2624 | 2632 |
2625 // Add a dummy call to the wasm function so that the generated wrapper | 2633 // Add a dummy call to the wasm function so that the generated wrapper |
2626 // contains a reference to the wrapped wasm function. Without this reference | 2634 // contains a reference to the wrapped wasm function. Without this reference |
2627 // the wasm function could not be re-imported into another wasm module. | 2635 // the wasm function could not be re-imported into another wasm module. |
2628 int pos = 0; | 2636 int pos = 0; |
2629 args[pos++] = HeapConstant(wasm_code); | 2637 args[pos++] = HeapConstant(wasm_code); |
2630 args[pos++] = *effect_; | 2638 args[pos++] = *effect_; |
2631 args[pos++] = *control_; | 2639 args[pos++] = *control_; |
2632 | 2640 |
2633 // We only need a dummy call descriptor. | 2641 // We only need a dummy call descriptor. |
(...skipping 19 matching lines...) Expand all Loading... |
2653 args[pos++] = *control_; | 2661 args[pos++] = *control_; |
2654 | 2662 |
2655 // Call the WASM code. | 2663 // Call the WASM code. |
2656 CallDescriptor* desc = | 2664 CallDescriptor* desc = |
2657 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); | 2665 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); |
2658 | 2666 |
2659 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); | 2667 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); |
2660 *effect_ = call; | 2668 *effect_ = call; |
2661 | 2669 |
2662 // Clear the ThreadInWasmFlag | 2670 // Clear the ThreadInWasmFlag |
2663 BuildModifyThreadInWasmFlag(false, jsgraph(), effect_, *control_); | 2671 BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_, |
| 2672 *control_); |
2664 | 2673 |
2665 Node* retval = call; | 2674 Node* retval = call; |
2666 Node* jsval = ToJS( | 2675 Node* jsval = ToJS( |
2667 retval, sig->return_count() == 0 ? wasm::kWasmStmt : sig->GetReturn()); | 2676 retval, sig->return_count() == 0 ? wasm::kWasmStmt : sig->GetReturn()); |
2668 Return(jsval); | 2677 Return(jsval); |
2669 } | 2678 } |
2670 | 2679 |
2671 int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count, | 2680 int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count, |
2672 wasm::FunctionSig* sig) { | 2681 wasm::FunctionSig* sig) { |
2673 // Convert WASM numbers to JS values. | 2682 // Convert WASM numbers to JS values. |
(...skipping 17 matching lines...) Expand all Loading... |
2691 Node* start = Start(wasm_count + 3); | 2700 Node* start = Start(wasm_count + 3); |
2692 *effect_ = start; | 2701 *effect_ = start; |
2693 *control_ = start; | 2702 *control_ = start; |
2694 | 2703 |
2695 if (!wasm::IsJSCompatibleSignature(sig_)) { | 2704 if (!wasm::IsJSCompatibleSignature(sig_)) { |
2696 // Throw a TypeError. Embedding the context is ok here, since this code is | 2705 // Throw a TypeError. Embedding the context is ok here, since this code is |
2697 // regenerated at instantiation time. | 2706 // regenerated at instantiation time. |
2698 Node* context = | 2707 Node* context = |
2699 jsgraph()->HeapConstant(jsgraph()->isolate()->native_context()); | 2708 jsgraph()->HeapConstant(jsgraph()->isolate()->native_context()); |
2700 BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), | 2709 BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), |
2701 context, nullptr, 0, effect_, control_); | 2710 centry_stub_node_, context, nullptr, 0, |
| 2711 effect_, control_); |
2702 // We don't need to return a value here, as the runtime call will not return | 2712 // We don't need to return a value here, as the runtime call will not return |
2703 // anyway (the c entry stub will trigger stack unwinding). | 2713 // anyway (the c entry stub will trigger stack unwinding). |
2704 ReturnVoid(); | 2714 ReturnVoid(); |
2705 return; | 2715 return; |
2706 } | 2716 } |
2707 | 2717 |
2708 Node** args = Buffer(wasm_count + 7); | 2718 Node** args = Buffer(wasm_count + 7); |
2709 | 2719 |
2710 Node* call = nullptr; | 2720 Node* call = nullptr; |
2711 | 2721 |
2712 BuildModifyThreadInWasmFlag(false, jsgraph(), effect_, *control_); | 2722 BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_, |
| 2723 *control_); |
2713 | 2724 |
2714 if (target->IsJSFunction()) { | 2725 if (target->IsJSFunction()) { |
2715 Handle<JSFunction> function = Handle<JSFunction>::cast(target); | 2726 Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
2716 if (function->shared()->internal_formal_parameter_count() == wasm_count) { | 2727 if (function->shared()->internal_formal_parameter_count() == wasm_count) { |
2717 int pos = 0; | 2728 int pos = 0; |
2718 args[pos++] = jsgraph()->Constant(target); // target callable. | 2729 args[pos++] = jsgraph()->Constant(target); // target callable. |
2719 // Receiver. | 2730 // Receiver. |
2720 if (is_sloppy(function->shared()->language_mode()) && | 2731 if (is_sloppy(function->shared()->language_mode()) && |
2721 !function->shared()->native()) { | 2732 !function->shared()->native()) { |
2722 args[pos++] = | 2733 args[pos++] = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 args[pos++] = HeapConstant(isolate->native_context()); | 2778 args[pos++] = HeapConstant(isolate->native_context()); |
2768 args[pos++] = *effect_; | 2779 args[pos++] = *effect_; |
2769 args[pos++] = *control_; | 2780 args[pos++] = *control_; |
2770 | 2781 |
2771 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | 2782 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); |
2772 } | 2783 } |
2773 | 2784 |
2774 *effect_ = call; | 2785 *effect_ = call; |
2775 SetSourcePosition(call, 0); | 2786 SetSourcePosition(call, 0); |
2776 | 2787 |
2777 BuildModifyThreadInWasmFlag(true, jsgraph(), effect_, *control_); | 2788 BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_, |
| 2789 *control_); |
2778 | 2790 |
2779 // Convert the return value back. | 2791 // Convert the return value back. |
2780 Node* val = sig->return_count() == 0 | 2792 Node* val = sig->return_count() == 0 |
2781 ? jsgraph()->Int32Constant(0) | 2793 ? jsgraph()->Int32Constant(0) |
2782 : FromJS(call, HeapConstant(isolate->native_context()), | 2794 : FromJS(call, HeapConstant(isolate->native_context()), |
2783 sig->GetReturn()); | 2795 sig->GetReturn()); |
2784 Return(val); | 2796 Return(val); |
2785 } | 2797 } |
2786 | 2798 |
2787 void WasmGraphBuilder::BuildWasmInterpreterEntry( | 2799 void WasmGraphBuilder::BuildWasmInterpreterEntry( |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2852 DCHECK_EQ(args_size_bytes, offset); | 2864 DCHECK_EQ(args_size_bytes, offset); |
2853 | 2865 |
2854 // We are passing the raw arg_buffer here. To the GC and other parts, it looks | 2866 // We are passing the raw arg_buffer here. To the GC and other parts, it looks |
2855 // like a Smi (lowest bit not set). In the runtime function however, don't | 2867 // like a Smi (lowest bit not set). In the runtime function however, don't |
2856 // call Smi::value on it, but just cast it to a byte pointer. | 2868 // call Smi::value on it, but just cast it to a byte pointer. |
2857 Node* parameters[] = { | 2869 Node* parameters[] = { |
2858 jsgraph()->HeapConstant(instance), // wasm instance | 2870 jsgraph()->HeapConstant(instance), // wasm instance |
2859 jsgraph()->SmiConstant(function_index), // function index | 2871 jsgraph()->SmiConstant(function_index), // function index |
2860 arg_buffer, // argument buffer | 2872 arg_buffer, // argument buffer |
2861 }; | 2873 }; |
2862 BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), parameters, | 2874 BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), centry_stub_node_, |
2863 arraysize(parameters), effect_, control_); | 2875 parameters, arraysize(parameters), effect_, control_); |
2864 | 2876 |
2865 // Read back the return value. | 2877 // Read back the return value. |
2866 if (sig->return_count() == 0) { | 2878 if (sig->return_count() == 0) { |
2867 Return(Int32Constant(0)); | 2879 Return(Int32Constant(0)); |
2868 } else if (Int64Lowering::IsI64AsTwoParameters(jsgraph()->machine(), | 2880 } else if (Int64Lowering::IsI64AsTwoParameters(jsgraph()->machine(), |
2869 sig->GetReturn())) { | 2881 sig->GetReturn())) { |
2870 MachineType load_rep = wasm::WasmOpcodes::MachineTypeFor(wasm::kWasmI32); | 2882 MachineType load_rep = wasm::WasmOpcodes::MachineTypeFor(wasm::kWasmI32); |
2871 Node* lower = | 2883 Node* lower = |
2872 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer, | 2884 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer, |
2873 Int32Constant(kInt64LowerHalfMemoryOffset), *effect_, | 2885 Int32Constant(kInt64LowerHalfMemoryOffset), *effect_, |
(...skipping 26 matching lines...) Expand all Loading... |
2900 } else { | 2912 } else { |
2901 return jsgraph()->RelocatableIntPtrConstant( | 2913 return jsgraph()->RelocatableIntPtrConstant( |
2902 mem_start + offset, RelocInfo::WASM_MEMORY_REFERENCE); | 2914 mem_start + offset, RelocInfo::WASM_MEMORY_REFERENCE); |
2903 } | 2915 } |
2904 } | 2916 } |
2905 | 2917 |
2906 Node* WasmGraphBuilder::CurrentMemoryPages() { | 2918 Node* WasmGraphBuilder::CurrentMemoryPages() { |
2907 // CurrentMemoryPages will not be called from asm.js, hence we cannot be in | 2919 // CurrentMemoryPages will not be called from asm.js, hence we cannot be in |
2908 // lazy-compilation mode, hence the instance will be set. | 2920 // lazy-compilation mode, hence the instance will be set. |
2909 DCHECK_EQ(wasm::kWasmOrigin, module_->module->get_origin()); | 2921 DCHECK_EQ(wasm::kWasmOrigin, module_->module->get_origin()); |
2910 DCHECK_NOT_NULL(module_); | 2922 Node* call = |
2911 DCHECK_NOT_NULL(module_->instance); | 2923 BuildCallToRuntime(Runtime::kWasmMemorySize, jsgraph(), centry_stub_node_, |
2912 Node* call = BuildCallToRuntime(Runtime::kWasmMemorySize, jsgraph(), nullptr, | 2924 nullptr, 0, effect_, control_); |
2913 0, effect_, control_); | |
2914 Node* result = BuildChangeSmiToInt32(call); | 2925 Node* result = BuildChangeSmiToInt32(call); |
2915 return result; | 2926 return result; |
2916 } | 2927 } |
2917 | 2928 |
2918 Node* WasmGraphBuilder::MemSize() { | 2929 Node* WasmGraphBuilder::MemSize() { |
2919 DCHECK_NOT_NULL(module_); | 2930 DCHECK_NOT_NULL(module_); |
2920 if (mem_size_) return mem_size_; | 2931 if (mem_size_) return mem_size_; |
2921 uint32_t size = module_->instance ? module_->instance->mem_size : 0; | 2932 uint32_t size = module_->instance ? module_->instance->mem_size : 0; |
2922 mem_size_ = jsgraph()->RelocatableInt32Constant( | 2933 mem_size_ = jsgraph()->RelocatableInt32Constant( |
2923 size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); | 2934 size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3679 Zone zone(isolate->allocator(), ZONE_NAME); | 3690 Zone zone(isolate->allocator(), ZONE_NAME); |
3680 Graph graph(&zone); | 3691 Graph graph(&zone); |
3681 CommonOperatorBuilder common(&zone); | 3692 CommonOperatorBuilder common(&zone); |
3682 MachineOperatorBuilder machine(&zone); | 3693 MachineOperatorBuilder machine(&zone); |
3683 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3694 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
3684 | 3695 |
3685 Node* control = nullptr; | 3696 Node* control = nullptr; |
3686 Node* effect = nullptr; | 3697 Node* effect = nullptr; |
3687 | 3698 |
3688 wasm::ModuleEnv module_env(module, nullptr); | 3699 wasm::ModuleEnv module_env(module, nullptr); |
3689 WasmGraphBuilder builder(&module_env, &zone, &jsgraph, func->sig); | 3700 WasmGraphBuilder builder(&module_env, &zone, &jsgraph, |
| 3701 CEntryStub(isolate, 1).GetCode(), func->sig); |
3690 builder.set_control_ptr(&control); | 3702 builder.set_control_ptr(&control); |
3691 builder.set_effect_ptr(&effect); | 3703 builder.set_effect_ptr(&effect); |
3692 builder.BuildJSToWasmWrapper(wasm_code, func->sig); | 3704 builder.BuildJSToWasmWrapper(wasm_code, func->sig); |
3693 | 3705 |
3694 //---------------------------------------------------------------------------- | 3706 //---------------------------------------------------------------------------- |
3695 // Run the compilation pipeline. | 3707 // Run the compilation pipeline. |
3696 //---------------------------------------------------------------------------- | 3708 //---------------------------------------------------------------------------- |
3697 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 3709 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
3698 OFStream os(stdout); | 3710 OFStream os(stdout); |
3699 os << "-- Graph after change lowering -- " << std::endl; | 3711 os << "-- Graph after change lowering -- " << std::endl; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3758 MachineOperatorBuilder machine(&zone); | 3770 MachineOperatorBuilder machine(&zone); |
3759 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3771 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
3760 | 3772 |
3761 Node* control = nullptr; | 3773 Node* control = nullptr; |
3762 Node* effect = nullptr; | 3774 Node* effect = nullptr; |
3763 | 3775 |
3764 SourcePositionTable* source_position_table = | 3776 SourcePositionTable* source_position_table = |
3765 origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph) | 3777 origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph) |
3766 : nullptr; | 3778 : nullptr; |
3767 | 3779 |
3768 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig, | 3780 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, |
| 3781 CEntryStub(isolate, 1).GetCode(), sig, |
3769 source_position_table); | 3782 source_position_table); |
3770 builder.set_control_ptr(&control); | 3783 builder.set_control_ptr(&control); |
3771 builder.set_effect_ptr(&effect); | 3784 builder.set_effect_ptr(&effect); |
3772 builder.BuildWasmToJSWrapper(target, sig); | 3785 builder.BuildWasmToJSWrapper(target, sig); |
3773 | 3786 |
3774 Handle<Code> code = Handle<Code>::null(); | 3787 Handle<Code> code = Handle<Code>::null(); |
3775 { | 3788 { |
3776 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 3789 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
3777 OFStream os(stdout); | 3790 OFStream os(stdout); |
3778 os << "-- Graph after change lowering -- " << std::endl; | 3791 os << "-- Graph after change lowering -- " << std::endl; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3840 //---------------------------------------------------------------------------- | 3853 //---------------------------------------------------------------------------- |
3841 Zone zone(isolate->allocator(), ZONE_NAME); | 3854 Zone zone(isolate->allocator(), ZONE_NAME); |
3842 Graph graph(&zone); | 3855 Graph graph(&zone); |
3843 CommonOperatorBuilder common(&zone); | 3856 CommonOperatorBuilder common(&zone); |
3844 MachineOperatorBuilder machine(&zone); | 3857 MachineOperatorBuilder machine(&zone); |
3845 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3858 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
3846 | 3859 |
3847 Node* control = nullptr; | 3860 Node* control = nullptr; |
3848 Node* effect = nullptr; | 3861 Node* effect = nullptr; |
3849 | 3862 |
3850 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); | 3863 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, |
| 3864 CEntryStub(isolate, 1).GetCode(), sig); |
3851 builder.set_control_ptr(&control); | 3865 builder.set_control_ptr(&control); |
3852 builder.set_effect_ptr(&effect); | 3866 builder.set_effect_ptr(&effect); |
3853 builder.BuildWasmInterpreterEntry(func_index, sig, instance); | 3867 builder.BuildWasmInterpreterEntry(func_index, sig, instance); |
3854 | 3868 |
3855 Handle<Code> code = Handle<Code>::null(); | 3869 Handle<Code> code = Handle<Code>::null(); |
3856 { | 3870 { |
3857 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 3871 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
3858 OFStream os(stdout); | 3872 OFStream os(stdout); |
3859 os << "-- Wasm to interpreter graph -- " << std::endl; | 3873 os << "-- Wasm to interpreter graph -- " << std::endl; |
3860 os << AsRPO(graph); | 3874 os << AsRPO(graph); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3905 decode_timer.Start(); | 3919 decode_timer.Start(); |
3906 } | 3920 } |
3907 // Create a TF graph during decoding. | 3921 // Create a TF graph during decoding. |
3908 | 3922 |
3909 Graph* graph = jsgraph_->graph(); | 3923 Graph* graph = jsgraph_->graph(); |
3910 CommonOperatorBuilder* common = jsgraph_->common(); | 3924 CommonOperatorBuilder* common = jsgraph_->common(); |
3911 MachineOperatorBuilder* machine = jsgraph_->machine(); | 3925 MachineOperatorBuilder* machine = jsgraph_->machine(); |
3912 SourcePositionTable* source_position_table = | 3926 SourcePositionTable* source_position_table = |
3913 new (jsgraph_->zone()) SourcePositionTable(graph); | 3927 new (jsgraph_->zone()) SourcePositionTable(graph); |
3914 WasmGraphBuilder builder(module_env_, jsgraph_->zone(), jsgraph_, | 3928 WasmGraphBuilder builder(module_env_, jsgraph_->zone(), jsgraph_, |
3915 func_body_.sig, source_position_table); | 3929 centry_stub_, func_body_.sig, source_position_table); |
3916 graph_construction_result_ = | 3930 graph_construction_result_ = |
3917 wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); | 3931 wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); |
3918 | 3932 |
3919 if (graph_construction_result_.failed()) { | 3933 if (graph_construction_result_.failed()) { |
3920 if (FLAG_trace_wasm_compiler) { | 3934 if (FLAG_trace_wasm_compiler) { |
3921 OFStream os(stdout); | 3935 OFStream os(stdout); |
3922 os << "Compilation failed: " << graph_construction_result_.error_msg() | 3936 os << "Compilation failed: " << graph_construction_result_.error_msg() |
3923 << std::endl; | 3937 << std::endl; |
3924 } | 3938 } |
3925 return nullptr; | 3939 return nullptr; |
(...skipping 16 matching lines...) Expand all Loading... |
3942 *decode_ms = decode_timer.Elapsed().InMillisecondsF(); | 3956 *decode_ms = decode_timer.Elapsed().InMillisecondsF(); |
3943 } | 3957 } |
3944 return source_position_table; | 3958 return source_position_table; |
3945 } | 3959 } |
3946 | 3960 |
3947 namespace { | 3961 namespace { |
3948 Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) { | 3962 Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) { |
3949 if (!name.is_empty()) { | 3963 if (!name.is_empty()) { |
3950 return name; | 3964 return name; |
3951 } | 3965 } |
| 3966 #ifndef DEBUG |
| 3967 return {}; |
| 3968 #endif |
3952 constexpr int kBufferLength = 15; | 3969 constexpr int kBufferLength = 15; |
3953 | 3970 |
3954 EmbeddedVector<char, kBufferLength> name_vector; | 3971 EmbeddedVector<char, kBufferLength> name_vector; |
3955 int name_len = SNPrintF(name_vector, "wasm#%d", index); | 3972 int name_len = SNPrintF(name_vector, "wasm#%d", index); |
3956 DCHECK(name_len > 0 && name_len < name_vector.length()); | 3973 DCHECK(name_len > 0 && name_len < name_vector.length()); |
3957 | 3974 |
3958 char* index_name = zone->NewArray<char>(name_len); | 3975 char* index_name = zone->NewArray<char>(name_len); |
3959 memcpy(index_name, name_vector.start(), name_len); | 3976 memcpy(index_name, name_vector.start(), name_len); |
3960 return Vector<const char>(index_name, name_len); | 3977 return Vector<const char>(index_name, name_len); |
3961 } | 3978 } |
(...skipping 15 matching lines...) Expand all Loading... |
3977 WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, | 3994 WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, |
3978 wasm::ModuleEnv* module_env, | 3995 wasm::ModuleEnv* module_env, |
3979 wasm::FunctionBody body, | 3996 wasm::FunctionBody body, |
3980 wasm::WasmName name, int index, | 3997 wasm::WasmName name, int index, |
3981 bool is_sync) | 3998 bool is_sync) |
3982 : isolate_(isolate), | 3999 : isolate_(isolate), |
3983 module_env_(module_env), | 4000 module_env_(module_env), |
3984 func_body_(body), | 4001 func_body_(body), |
3985 func_name_(name), | 4002 func_name_(name), |
3986 is_sync_(is_sync), | 4003 is_sync_(is_sync), |
3987 graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)), | 4004 centry_stub_(CEntryStub(isolate, 1).GetCode()), |
3988 jsgraph_(new (graph_zone()) JSGraph( | 4005 func_index_(index) {} |
3989 isolate, new (graph_zone()) Graph(graph_zone()), | |
3990 new (graph_zone()) CommonOperatorBuilder(graph_zone()), nullptr, | |
3991 nullptr, | |
3992 new (graph_zone()) MachineOperatorBuilder( | |
3993 graph_zone(), MachineType::PointerRepresentation(), | |
3994 InstructionSelector::SupportedMachineOperatorFlags(), | |
3995 InstructionSelector::AlignmentRequirements()))), | |
3996 compilation_zone_(isolate->allocator(), ZONE_NAME), | |
3997 info_(GetDebugName(&compilation_zone_, name, index), isolate, | |
3998 &compilation_zone_, Code::ComputeFlags(Code::WASM_FUNCTION)), | |
3999 func_index_(index), | |
4000 protected_instructions_(&compilation_zone_) {} | |
4001 | |
4002 void WasmCompilationUnit::InitializeHandles() { | |
4003 // Create and cache this node in the main thread, which contains a handle to | |
4004 // the code object of the c-entry stub. | |
4005 jsgraph_->CEntryStubConstant(1); | |
4006 DCHECK(!handles_initialized_); | |
4007 #if DEBUG | |
4008 handles_initialized_ = true; | |
4009 #endif // DEBUG | |
4010 } | |
4011 | 4006 |
4012 void WasmCompilationUnit::ExecuteCompilation() { | 4007 void WasmCompilationUnit::ExecuteCompilation() { |
4013 DCHECK(handles_initialized_); | |
4014 if (is_sync_) { | 4008 if (is_sync_) { |
4015 // TODO(karlschimpf): Make this work when asynchronous. | 4009 // TODO(karlschimpf): Make this work when asynchronous. |
4016 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 4010 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
4017 HistogramTimerScope wasm_compile_function_time_scope( | 4011 HistogramTimerScope wasm_compile_function_time_scope( |
4018 isolate_->counters()->wasm_compile_function_time()); | 4012 isolate_->counters()->wasm_compile_function_time()); |
4019 ExecuteCompilationInternal(); | 4013 ExecuteCompilationInternal(); |
4020 return; | |
4021 } | 4014 } |
4022 ExecuteCompilationInternal(); | 4015 ExecuteCompilationInternal(); |
| 4016 // Record the memory cost this unit places on the system until |
| 4017 // it is finalized. That may be "0" in error cases. |
| 4018 if (job_) { |
| 4019 size_t cost = job_->AllocatedMemory(); |
| 4020 set_memory_cost(cost); |
| 4021 } |
4023 } | 4022 } |
4024 | 4023 |
4025 void WasmCompilationUnit::ExecuteCompilationInternal() { | 4024 void WasmCompilationUnit::ExecuteCompilationInternal() { |
4026 if (FLAG_trace_wasm_compiler) { | 4025 if (FLAG_trace_wasm_compiler) { |
4027 if (func_name_.start() != nullptr) { | 4026 if (func_name_.start() != nullptr) { |
4028 PrintF("Compiling WASM function %d:'%.*s'\n\n", func_index(), | 4027 PrintF("Compiling WASM function %d:'%.*s'\n\n", func_index(), |
4029 func_name_.length(), func_name_.start()); | 4028 func_name_.length(), func_name_.start()); |
4030 } else { | 4029 } else { |
4031 PrintF("Compiling WASM function %d:<unnamed>\n\n", func_index()); | 4030 PrintF("Compiling WASM function %d:<unnamed>\n\n", func_index()); |
4032 } | 4031 } |
4033 } | 4032 } |
4034 | 4033 |
4035 double decode_ms = 0; | 4034 double decode_ms = 0; |
4036 size_t node_count = 0; | 4035 size_t node_count = 0; |
4037 | 4036 |
4038 std::unique_ptr<Zone> graph_zone(graph_zone_.release()); | 4037 Zone graph_zone(isolate_->allocator(), ZONE_NAME); |
| 4038 jsgraph_ = new (&graph_zone) JSGraph( |
| 4039 isolate_, new (&graph_zone) Graph(&graph_zone), |
| 4040 new (&graph_zone) CommonOperatorBuilder(&graph_zone), nullptr, nullptr, |
| 4041 new (&graph_zone) MachineOperatorBuilder( |
| 4042 &graph_zone, MachineType::PointerRepresentation(), |
| 4043 InstructionSelector::SupportedMachineOperatorFlags(), |
| 4044 InstructionSelector::AlignmentRequirements())); |
4039 SourcePositionTable* source_positions = BuildGraphForWasmFunction(&decode_ms); | 4045 SourcePositionTable* source_positions = BuildGraphForWasmFunction(&decode_ms); |
4040 | 4046 |
4041 if (graph_construction_result_.failed()) { | 4047 if (graph_construction_result_.failed()) { |
4042 ok_ = false; | 4048 ok_ = false; |
4043 return; | 4049 return; |
4044 } | 4050 } |
4045 | 4051 |
4046 base::ElapsedTimer pipeline_timer; | 4052 base::ElapsedTimer pipeline_timer; |
4047 if (FLAG_trace_wasm_decode_time) { | 4053 if (FLAG_trace_wasm_decode_time) { |
4048 node_count = jsgraph_->graph()->NodeCount(); | 4054 node_count = jsgraph_->graph()->NodeCount(); |
4049 pipeline_timer.Start(); | 4055 pipeline_timer.Start(); |
4050 } | 4056 } |
4051 | 4057 |
| 4058 compilation_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME)); |
| 4059 |
4052 // Run the compiler pipeline to generate machine code. | 4060 // Run the compiler pipeline to generate machine code. |
4053 CallDescriptor* descriptor = wasm::ModuleEnv::GetWasmCallDescriptor( | 4061 CallDescriptor* descriptor = wasm::ModuleEnv::GetWasmCallDescriptor( |
4054 &compilation_zone_, func_body_.sig); | 4062 compilation_zone_.get(), func_body_.sig); |
4055 if (jsgraph_->machine()->Is32()) { | 4063 if (jsgraph_->machine()->Is32()) { |
4056 descriptor = | 4064 descriptor = module_env_->GetI32WasmCallDescriptor(compilation_zone_.get(), |
4057 module_env_->GetI32WasmCallDescriptor(&compilation_zone_, descriptor); | 4065 descriptor); |
4058 } | 4066 } |
| 4067 info_.reset(new CompilationInfo( |
| 4068 GetDebugName(compilation_zone_.get(), func_name_, func_index_), isolate_, |
| 4069 compilation_zone_.get(), Code::ComputeFlags(Code::WASM_FUNCTION))); |
| 4070 ZoneVector<trap_handler::ProtectedInstructionData> protected_instructions( |
| 4071 compilation_zone_.get()); |
| 4072 |
4059 job_.reset(Pipeline::NewWasmCompilationJob( | 4073 job_.reset(Pipeline::NewWasmCompilationJob( |
4060 &info_, jsgraph_, descriptor, source_positions, &protected_instructions_, | 4074 info_.get(), jsgraph_, descriptor, source_positions, |
4061 !module_env_->module->is_wasm())); | 4075 &protected_instructions, !module_env_->module->is_wasm())); |
4062 ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; | 4076 ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; |
4063 // TODO(bradnelson): Improve histogram handling of size_t. | 4077 // TODO(bradnelson): Improve histogram handling of size_t. |
4064 if (is_sync_) | 4078 if (is_sync_) |
4065 // TODO(karlschimpf): Make this work when asynchronous. | 4079 // TODO(karlschimpf): Make this work when asynchronous. |
4066 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 4080 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
4067 isolate_->counters()->wasm_compile_function_peak_memory_bytes()->AddSample( | 4081 isolate_->counters()->wasm_compile_function_peak_memory_bytes()->AddSample( |
4068 static_cast<int>(jsgraph_->graph()->zone()->allocation_size())); | 4082 static_cast<int>(jsgraph_->graph()->zone()->allocation_size())); |
4069 | 4083 |
4070 if (FLAG_trace_wasm_decode_time) { | 4084 if (FLAG_trace_wasm_decode_time) { |
4071 double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF(); | 4085 double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF(); |
4072 PrintF( | 4086 PrintF( |
4073 "wasm-compilation phase 1 ok: %u bytes, %0.3f ms decode, %zu nodes, " | 4087 "wasm-compilation phase 1 ok: %u bytes, %0.3f ms decode, %zu nodes, " |
4074 "%0.3f ms pipeline\n", | 4088 "%0.3f ms pipeline\n", |
4075 static_cast<unsigned>(func_body_.end - func_body_.start), decode_ms, | 4089 static_cast<unsigned>(func_body_.end - func_body_.start), decode_ms, |
4076 node_count, pipeline_ms); | 4090 node_count, pipeline_ms); |
4077 } | 4091 } |
| 4092 // The graph zone is about to get out of scope. Avoid invalid references. |
| 4093 jsgraph_ = nullptr; |
4078 } | 4094 } |
4079 | 4095 |
4080 Handle<Code> WasmCompilationUnit::FinishCompilation( | 4096 Handle<Code> WasmCompilationUnit::FinishCompilation( |
4081 wasm::ErrorThrower* thrower) { | 4097 wasm::ErrorThrower* thrower) { |
4082 if (!ok_) { | 4098 if (!ok_) { |
4083 if (graph_construction_result_.failed()) { | 4099 if (graph_construction_result_.failed()) { |
4084 // Add the function as another context for the exception | 4100 // Add the function as another context for the exception |
4085 ScopedVector<char> buffer(128); | 4101 ScopedVector<char> buffer(128); |
4086 if (func_name_.start() == nullptr) { | 4102 if (func_name_.start() == nullptr) { |
4087 SNPrintF(buffer, | 4103 SNPrintF(buffer, |
4088 "Compiling WASM function #%d:%.*s failed:", func_index_, | 4104 "Compiling WASM function #%d:%.*s failed:", func_index_, |
4089 func_name_.length(), func_name_.start()); | 4105 func_name_.length(), func_name_.start()); |
4090 } else { | 4106 } else { |
4091 SNPrintF(buffer, "Compiling WASM function #%d failed:", func_index_); | 4107 SNPrintF(buffer, "Compiling WASM function #%d failed:", func_index_); |
4092 } | 4108 } |
4093 thrower->CompileFailed(buffer.start(), graph_construction_result_); | 4109 thrower->CompileFailed(buffer.start(), graph_construction_result_); |
4094 } | 4110 } |
4095 | 4111 |
4096 return Handle<Code>::null(); | 4112 return Handle<Code>::null(); |
4097 } | 4113 } |
4098 base::ElapsedTimer codegen_timer; | 4114 base::ElapsedTimer codegen_timer; |
4099 if (FLAG_trace_wasm_decode_time) { | 4115 if (FLAG_trace_wasm_decode_time) { |
4100 codegen_timer.Start(); | 4116 codegen_timer.Start(); |
4101 } | 4117 } |
4102 if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { | 4118 if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { |
4103 return Handle<Code>::null(); | 4119 return Handle<Code>::null(); |
4104 } | 4120 } |
4105 Handle<Code> code = info_.code(); | 4121 Handle<Code> code = info_->code(); |
4106 DCHECK(!code.is_null()); | 4122 DCHECK(!code.is_null()); |
4107 | 4123 |
4108 if (isolate_->logger()->is_logging_code_events() || | 4124 if (isolate_->logger()->is_logging_code_events() || |
4109 isolate_->is_profiling()) { | 4125 isolate_->is_profiling()) { |
4110 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code, | 4126 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code, |
4111 "WASM_function", func_index_, | 4127 "WASM_function", func_index_, |
4112 wasm::WasmName("module"), func_name_); | 4128 wasm::WasmName("module"), func_name_); |
4113 } | 4129 } |
4114 | 4130 |
4115 if (FLAG_trace_wasm_decode_time) { | 4131 if (FLAG_trace_wasm_decode_time) { |
4116 double codegen_ms = codegen_timer.Elapsed().InMillisecondsF(); | 4132 double codegen_ms = codegen_timer.Elapsed().InMillisecondsF(); |
4117 PrintF("wasm-code-generation ok: %u bytes, %0.3f ms code generation\n", | 4133 PrintF("wasm-code-generation ok: %u bytes, %0.3f ms code generation\n", |
4118 static_cast<unsigned>(func_body_.end - func_body_.start), | 4134 static_cast<unsigned>(func_body_.end - func_body_.start), |
4119 codegen_ms); | 4135 codegen_ms); |
4120 } | 4136 } |
4121 | 4137 |
4122 return code; | 4138 return code; |
4123 } | 4139 } |
4124 | 4140 |
4125 // static | 4141 // static |
4126 Handle<Code> WasmCompilationUnit::CompileWasmFunction( | 4142 Handle<Code> WasmCompilationUnit::CompileWasmFunction( |
4127 wasm::ErrorThrower* thrower, Isolate* isolate, | 4143 wasm::ErrorThrower* thrower, Isolate* isolate, |
4128 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { | 4144 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { |
4129 WasmCompilationUnit unit(isolate, module_env, function); | 4145 WasmCompilationUnit unit(isolate, module_env, function); |
4130 unit.InitializeHandles(); | |
4131 unit.ExecuteCompilation(); | 4146 unit.ExecuteCompilation(); |
4132 return unit.FinishCompilation(thrower); | 4147 return unit.FinishCompilation(thrower); |
4133 } | 4148 } |
4134 | 4149 |
4135 } // namespace compiler | 4150 } // namespace compiler |
4136 } // namespace internal | 4151 } // namespace internal |
4137 } // namespace v8 | 4152 } // namespace v8 |
OLD | NEW |