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

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 2957693002: Merged changes to avoid OOM for large wasm modules. (Closed)
Patch Set: Created 3 years, 6 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/compiler/wasm-compiler.h ('k') | src/compiler/zone-stats.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/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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/compiler/zone-stats.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698