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

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

Issue 2174123002: [wasm] Add support for multiple indirect function tables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix GC issue Created 4 years, 4 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/wasm/module-decoder.cc » ('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/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 10
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 }; 271 };
272 272
273 WasmGraphBuilder::WasmGraphBuilder( 273 WasmGraphBuilder::WasmGraphBuilder(
274 Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* function_signature, 274 Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* function_signature,
275 compiler::SourcePositionTable* source_position_table) 275 compiler::SourcePositionTable* source_position_table)
276 : zone_(zone), 276 : zone_(zone),
277 jsgraph_(jsgraph), 277 jsgraph_(jsgraph),
278 module_(nullptr), 278 module_(nullptr),
279 mem_buffer_(nullptr), 279 mem_buffer_(nullptr),
280 mem_size_(nullptr), 280 mem_size_(nullptr),
281 function_table_(nullptr), 281 function_tables_(zone),
282 control_(nullptr), 282 control_(nullptr),
283 effect_(nullptr), 283 effect_(nullptr),
284 cur_buffer_(def_buffer_), 284 cur_buffer_(def_buffer_),
285 cur_bufsize_(kDefaultBufferSize), 285 cur_bufsize_(kDefaultBufferSize),
286 trap_(new (zone) WasmTrapHelper(this)), 286 trap_(new (zone) WasmTrapHelper(this)),
287 function_signature_(function_signature), 287 function_signature_(function_signature),
288 source_position_table_(source_position_table) { 288 source_position_table_(source_position_table) {
289 DCHECK_NOT_NULL(jsgraph_); 289 DCHECK_NOT_NULL(jsgraph_);
290 } 290 }
291 291
(...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, 2052 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args,
2053 wasm::WasmCodePosition position) { 2053 wasm::WasmCodePosition position) {
2054 DCHECK_NOT_NULL(args[0]); 2054 DCHECK_NOT_NULL(args[0]);
2055 DCHECK(module_ && module_->instance); 2055 DCHECK(module_ && module_->instance);
2056 2056
2057 MachineOperatorBuilder* machine = jsgraph()->machine(); 2057 MachineOperatorBuilder* machine = jsgraph()->machine();
2058 2058
2059 // Compute the code object by loading it from the function table. 2059 // Compute the code object by loading it from the function table.
2060 Node* key = args[0]; 2060 Node* key = args[0];
2061 2061
2062 // Assume only one table for now.
2063 DCHECK_LE(module_->instance->function_tables.size(), 1u);
2062 // Bounds check the index. 2064 // Bounds check the index.
2063 int table_size = static_cast<int>(module_->FunctionTableSize()); 2065 uint32_t table_size =
2066 module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0;
2064 if (table_size > 0) { 2067 if (table_size > 0) {
2065 // Bounds check against the table size. 2068 // Bounds check against the table size.
2066 Node* size = Int32Constant(static_cast<int>(table_size)); 2069 Node* size = Uint32Constant(table_size);
2067 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 2070 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
2068 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position); 2071 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position);
2069 } else { 2072 } else {
2070 // No function table. Generate a trap and return a constant. 2073 // No function table. Generate a trap and return a constant.
2071 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2074 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2072 return trap_->GetTrapValue(module_->GetSignature(index)); 2075 return trap_->GetTrapValue(module_->GetSignature(index));
2073 } 2076 }
2074 Node* table = FunctionTable(); 2077 Node* table = FunctionTable(0);
2075 2078
2076 // Load signature from the table and check. 2079 // Load signature from the table and check.
2077 // The table is a FixedArray; signatures are encoded as SMIs. 2080 // The table is a FixedArray; signatures are encoded as SMIs.
2078 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 2081 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
2079 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 2082 ElementAccess access = AccessBuilder::ForFixedArrayElement();
2080 const int fixed_offset = access.header_size - access.tag(); 2083 const int fixed_offset = access.header_size - access.tag();
2081 { 2084 {
2082 Node* load_sig = graph()->NewNode( 2085 Node* load_sig = graph()->NewNode(
2083 machine->Load(MachineType::AnyTagged()), table, 2086 machine->Load(MachineType::AnyTagged()), table,
2084 graph()->NewNode(machine->Int32Add(), 2087 graph()->NewNode(machine->Int32Add(),
2085 graph()->NewNode(machine->Word32Shl(), key, 2088 graph()->NewNode(machine->Word32Shl(), key,
2086 Int32Constant(kPointerSizeLog2)), 2089 Int32Constant(kPointerSizeLog2)),
2087 Int32Constant(fixed_offset)), 2090 Int32Constant(fixed_offset)),
2088 *effect_, *control_); 2091 *effect_, *control_);
2089 Node* sig_match = 2092 Node* sig_match =
2090 graph()->NewNode(machine->Word32Equal(), 2093 graph()->NewNode(machine->Word32Equal(),
2091 BuildChangeSmiToInt32(load_sig), Int32Constant(index)); 2094 BuildChangeSmiToInt32(load_sig), Int32Constant(index));
2092 trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position); 2095 trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
2093 } 2096 }
2094 2097
2095 // Load code object from the table. 2098 // Load code object from the table.
2096 int offset = fixed_offset + kPointerSize * table_size; 2099 uint32_t offset = fixed_offset + kPointerSize * table_size;
2097 Node* load_code = graph()->NewNode( 2100 Node* load_code = graph()->NewNode(
2098 machine->Load(MachineType::AnyTagged()), table, 2101 machine->Load(MachineType::AnyTagged()), table,
2099 graph()->NewNode(machine->Int32Add(), 2102 graph()->NewNode(machine->Int32Add(),
2100 graph()->NewNode(machine->Word32Shl(), key, 2103 graph()->NewNode(machine->Word32Shl(), key,
2101 Int32Constant(kPointerSizeLog2)), 2104 Int32Constant(kPointerSizeLog2)),
2102 Int32Constant(offset)), 2105 Uint32Constant(offset)),
2103 *effect_, *control_); 2106 *effect_, *control_);
2104 2107
2105 args[0] = load_code; 2108 args[0] = load_code;
2106 wasm::FunctionSig* sig = module_->GetSignature(index); 2109 wasm::FunctionSig* sig = module_->GetSignature(index);
2107 return BuildWasmCall(sig, args, position); 2110 return BuildWasmCall(sig, args, position);
2108 } 2111 }
2109 2112
2110 Node* WasmGraphBuilder::JITSingleFunction(Node* const base, Node* const length, 2113 Node* WasmGraphBuilder::JITSingleFunction(Node* const base, Node* const length,
2111 Node* const index, 2114 Node* const index,
2112 const uint32_t sig_index, 2115 const uint32_t sig_index,
(...skipping 11 matching lines...) Expand all
2124 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position); 2127 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position);
2125 2128
2126 Node* in_bounds = graph()->NewNode( 2129 Node* in_bounds = graph()->NewNode(
2127 machine->Uint32LessThanOrEqual(), 2130 machine->Uint32LessThanOrEqual(),
2128 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0)); 2131 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0));
2129 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position); 2132 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position);
2130 } 2133 }
2131 2134
2132 // Bounds check the index. 2135 // Bounds check the index.
2133 { 2136 {
2134 int table_size = static_cast<int>(module_->FunctionTableSize()); 2137 // Assume only one table for now.
2138 DCHECK_LE(module_->instance->function_tables.size(), 1u);
2139 uint32_t table_size =
2140 module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0;
2135 if (table_size > 0) { 2141 if (table_size > 0) {
2136 // Bounds check against the table size. 2142 // Bounds check against the table size.
2137 Node* size = Int32Constant(static_cast<int>(table_size)); 2143 Node* size = Uint32Constant(table_size);
2138 Node* in_bounds = 2144 Node* in_bounds =
2139 graph()->NewNode(machine->Uint32LessThan(), index, size); 2145 graph()->NewNode(machine->Uint32LessThan(), index, size);
2140 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position); 2146 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position);
2141 } else { 2147 } else {
2142 // No function table. Generate a trap and return a constant. 2148 // No function table. Generate a trap and return a constant.
2143 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2149 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2144 return trap_->GetTrapValue(module_->GetSignature(sig_index)); 2150 return trap_->GetTrapValue(module_->GetSignature(sig_index));
2145 } 2151 }
2146 } 2152 }
2147 2153
2148 const size_t runtime_input_params = 7; 2154 const size_t runtime_input_params = 7;
2149 const size_t runtime_env_params = 5; 2155 const size_t runtime_env_params = 5;
2150 2156
2151 Runtime::FunctionId f = Runtime::kJITSingleFunction; 2157 Runtime::FunctionId f = Runtime::kJITSingleFunction;
2152 const Runtime::Function* fun = Runtime::FunctionForId(f); 2158 const Runtime::Function* fun = Runtime::FunctionForId(f);
2153 // CEntryStubConstant nodes have to be created and cached in the main 2159 // CEntryStubConstant nodes have to be created and cached in the main
2154 // thread. At the moment this is only done for CEntryStubConstant(1). 2160 // thread. At the moment this is only done for CEntryStubConstant(1).
2155 DCHECK_EQ(1, fun->result_size); 2161 DCHECK_EQ(1, fun->result_size);
2156 const uint32_t return_count = static_cast<uint32_t>(sig->return_count()); 2162 const uint32_t return_count = static_cast<uint32_t>(sig->return_count());
2157 const uint32_t parameter_count = 2163 const uint32_t parameter_count =
2158 static_cast<uint32_t>(sig->parameter_count()); 2164 static_cast<uint32_t>(sig->parameter_count());
2159 2165
2160 const uint32_t inputs_size = runtime_input_params + runtime_env_params + 2166 const uint32_t inputs_size = runtime_input_params + runtime_env_params +
2161 return_count + parameter_count; 2167 return_count + parameter_count;
2162 Node** inputs = Buffer(inputs_size); 2168 Node** inputs = Buffer(inputs_size);
2163 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size); 2169 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size);
2164 inputs[1] = BuildChangeUint32ToSmi(base); 2170 inputs[1] = BuildChangeUint32ToSmi(base);
2165 inputs[2] = BuildChangeUint32ToSmi(length); 2171 inputs[2] = BuildChangeUint32ToSmi(length);
2166 inputs[3] = BuildChangeUint32ToSmi(index); 2172 inputs[3] = BuildChangeUint32ToSmi(index);
2167 inputs[4] = FunctionTable(); 2173 inputs[4] = FunctionTable(0);
2168 inputs[5] = Uint32Constant(sig_index); 2174 inputs[5] = Uint32Constant(sig_index);
2169 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count)); 2175 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count));
2170 2176
2171 // Pass in parameters and return types in to the runtime function 2177 // Pass in parameters and return types in to the runtime function
2172 // to allow it to regenerate signature 2178 // to allow it to regenerate signature
2173 for (uint32_t i = 0; i < return_count; ++i) { 2179 for (uint32_t i = 0; i < return_count; ++i) {
2174 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi( 2180 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi(
2175 Uint32Constant(static_cast<int>(sig->GetReturn(i)))); 2181 Uint32Constant(static_cast<int>(sig->GetReturn(i))));
2176 } 2182 }
2177 2183
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 2805 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
2800 } 2806 }
2801 } 2807 }
2802 2808
2803 Node* WasmGraphBuilder::DefaultS128Value() { 2809 Node* WasmGraphBuilder::DefaultS128Value() {
2804 Node* zero = jsgraph()->Int32Constant(0); 2810 Node* zero = jsgraph()->Int32Constant(0);
2805 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero, 2811 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero,
2806 zero, zero); 2812 zero, zero);
2807 } 2813 }
2808 2814
2809 Node* WasmGraphBuilder::FunctionTable() { 2815 Node* WasmGraphBuilder::FunctionTable(uint32_t index) {
2810 DCHECK(module_ && module_->instance && 2816 DCHECK(module_ && module_->instance &&
2811 !module_->instance->function_table.is_null()); 2817 index < module_->instance->function_tables.size());
2812 if (!function_table_) { 2818 if (!function_tables_.size()) {
2813 function_table_ = HeapConstant(module_->instance->function_table); 2819 for (size_t i = 0; i < module_->instance->function_tables.size(); ++i) {
2820 DCHECK(!module_->instance->function_tables[i].is_null());
2821 function_tables_.push_back(
2822 HeapConstant(module_->instance->function_tables[i]));
2823 }
2814 } 2824 }
2815 return function_table_; 2825 return function_tables_[index];
2816 } 2826 }
2817 2827
2818 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node, 2828 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node,
2819 Runtime::FunctionId function_id, 2829 Runtime::FunctionId function_id,
2820 Signature<Conversion>* signature) { 2830 Signature<Conversion>* signature) {
2821 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); 2831 SimplifiedOperatorBuilder simplified(jsgraph()->zone());
2822 const Runtime::Function* function = Runtime::FunctionForId(function_id); 2832 const Runtime::Function* function = Runtime::FunctionForId(function_id);
2823 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 2833 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
2824 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties, 2834 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties,
2825 CallDescriptor::kNoFlags); 2835 CallDescriptor::kNoFlags);
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 function_->code_start_offset), 3476 function_->code_start_offset),
3467 compile_ms); 3477 compile_ms);
3468 } 3478 }
3469 3479
3470 return code; 3480 return code;
3471 } 3481 }
3472 3482
3473 } // namespace compiler 3483 } // namespace compiler
3474 } // namespace internal 3484 } // namespace internal
3475 } // namespace v8 3485 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/wasm/module-decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698