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

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 loop bug, cleanups, style 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
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 "src/isolate-inl.h" 7 #include "src/isolate-inl.h"
8 8
9 #include "src/base/platform/elapsed-timer.h" 9 #include "src/base/platform/elapsed-timer.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 }; 269 };
270 270
271 WasmGraphBuilder::WasmGraphBuilder( 271 WasmGraphBuilder::WasmGraphBuilder(
272 Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* function_signature, 272 Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* function_signature,
273 compiler::SourcePositionTable* source_position_table) 273 compiler::SourcePositionTable* source_position_table)
274 : zone_(zone), 274 : zone_(zone),
275 jsgraph_(jsgraph), 275 jsgraph_(jsgraph),
276 module_(nullptr), 276 module_(nullptr),
277 mem_buffer_(nullptr), 277 mem_buffer_(nullptr),
278 mem_size_(nullptr), 278 mem_size_(nullptr),
279 function_table_(nullptr), 279 function_tables_(zone),
280 control_(nullptr), 280 control_(nullptr),
281 effect_(nullptr), 281 effect_(nullptr),
282 cur_buffer_(def_buffer_), 282 cur_buffer_(def_buffer_),
283 cur_bufsize_(kDefaultBufferSize), 283 cur_bufsize_(kDefaultBufferSize),
284 trap_(new (zone) WasmTrapHelper(this)), 284 trap_(new (zone) WasmTrapHelper(this)),
285 function_signature_(function_signature), 285 function_signature_(function_signature),
286 source_position_table_(source_position_table) { 286 source_position_table_(source_position_table) {
287 DCHECK_NOT_NULL(jsgraph_); 287 DCHECK_NOT_NULL(jsgraph_);
288 } 288 }
289 289
(...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after
2050 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, 2050 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args,
2051 wasm::WasmCodePosition position) { 2051 wasm::WasmCodePosition position) {
2052 DCHECK_NOT_NULL(args[0]); 2052 DCHECK_NOT_NULL(args[0]);
2053 DCHECK(module_ && module_->instance); 2053 DCHECK(module_ && module_->instance);
2054 2054
2055 MachineOperatorBuilder* machine = jsgraph()->machine(); 2055 MachineOperatorBuilder* machine = jsgraph()->machine();
2056 2056
2057 // Compute the code object by loading it from the function table. 2057 // Compute the code object by loading it from the function table.
2058 Node* key = args[0]; 2058 Node* key = args[0];
2059 2059
2060 // Assume only one table for now.
2061 DCHECK_EQ(module_->instance->function_tables.size(), 1);
2060 // Bounds check the index. 2062 // Bounds check the index.
2061 int table_size = static_cast<int>(module_->FunctionTableSize()); 2063 int table_size =
2064 module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0;
2062 if (table_size > 0) { 2065 if (table_size > 0) {
2063 // Bounds check against the table size. 2066 // Bounds check against the table size.
2064 Node* size = Int32Constant(static_cast<int>(table_size)); 2067 Node* size = Int32Constant(table_size);
2065 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 2068 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
2066 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position); 2069 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position);
2067 } else { 2070 } else {
2068 // No function table. Generate a trap and return a constant. 2071 // No function table. Generate a trap and return a constant.
2069 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2072 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2070 return trap_->GetTrapValue(module_->GetSignature(index)); 2073 return trap_->GetTrapValue(module_->GetSignature(index));
2071 } 2074 }
2072 Node* table = FunctionTable(); 2075 Node* table = FunctionTable(0);
2073 2076
2074 // Load signature from the table and check. 2077 // Load signature from the table and check.
2075 // The table is a FixedArray; signatures are encoded as SMIs. 2078 // The table is a FixedArray; signatures are encoded as SMIs.
2076 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 2079 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
2077 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 2080 ElementAccess access = AccessBuilder::ForFixedArrayElement();
2078 const int fixed_offset = access.header_size - access.tag(); 2081 const int fixed_offset = access.header_size - access.tag();
2079 { 2082 {
2080 Node* load_sig = graph()->NewNode( 2083 Node* load_sig = graph()->NewNode(
2081 machine->Load(MachineType::AnyTagged()), table, 2084 machine->Load(MachineType::AnyTagged()), table,
2082 graph()->NewNode(machine->Int32Add(), 2085 graph()->NewNode(machine->Int32Add(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position); 2125 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position);
2123 2126
2124 Node* in_bounds = graph()->NewNode( 2127 Node* in_bounds = graph()->NewNode(
2125 machine->Uint32LessThanOrEqual(), 2128 machine->Uint32LessThanOrEqual(),
2126 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0)); 2129 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0));
2127 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position); 2130 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position);
2128 } 2131 }
2129 2132
2130 // Bounds check the index. 2133 // Bounds check the index.
2131 { 2134 {
2132 int table_size = static_cast<int>(module_->FunctionTableSize()); 2135 // Assume only one table for now.
2136 DCHECK_EQ(module_->instance->function_tables.size(), 1);
2137 int table_size =
2138 module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0;
2133 if (table_size > 0) { 2139 if (table_size > 0) {
2134 // Bounds check against the table size. 2140 // Bounds check against the table size.
2135 Node* size = Int32Constant(static_cast<int>(table_size)); 2141 Node* size = Int32Constant(table_size);
2136 Node* in_bounds = 2142 Node* in_bounds =
2137 graph()->NewNode(machine->Uint32LessThan(), index, size); 2143 graph()->NewNode(machine->Uint32LessThan(), index, size);
2138 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position); 2144 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position);
2139 } else { 2145 } else {
2140 // No function table. Generate a trap and return a constant. 2146 // No function table. Generate a trap and return a constant.
2141 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2147 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2142 return trap_->GetTrapValue(module_->GetSignature(sig_index)); 2148 return trap_->GetTrapValue(module_->GetSignature(sig_index));
2143 } 2149 }
2144 } 2150 }
2145 2151
2146 const size_t runtime_input_params = 7; 2152 const size_t runtime_input_params = 7;
2147 const size_t runtime_env_params = 5; 2153 const size_t runtime_env_params = 5;
2148 2154
2149 Runtime::FunctionId f = Runtime::kJITSingleFunction; 2155 Runtime::FunctionId f = Runtime::kJITSingleFunction;
2150 const Runtime::Function* fun = Runtime::FunctionForId(f); 2156 const Runtime::Function* fun = Runtime::FunctionForId(f);
2151 // CEntryStubConstant nodes have to be created and cached in the main 2157 // CEntryStubConstant nodes have to be created and cached in the main
2152 // thread. At the moment this is only done for CEntryStubConstant(1). 2158 // thread. At the moment this is only done for CEntryStubConstant(1).
2153 DCHECK_EQ(1, fun->result_size); 2159 DCHECK_EQ(1, fun->result_size);
2154 const uint32_t return_count = static_cast<uint32_t>(sig->return_count()); 2160 const uint32_t return_count = static_cast<uint32_t>(sig->return_count());
2155 const uint32_t parameter_count = 2161 const uint32_t parameter_count =
2156 static_cast<uint32_t>(sig->parameter_count()); 2162 static_cast<uint32_t>(sig->parameter_count());
2157 2163
2158 const uint32_t inputs_size = runtime_input_params + runtime_env_params + 2164 const uint32_t inputs_size = runtime_input_params + runtime_env_params +
2159 return_count + parameter_count; 2165 return_count + parameter_count;
2160 Node** inputs = Buffer(inputs_size); 2166 Node** inputs = Buffer(inputs_size);
2161 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size); 2167 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size);
2162 inputs[1] = BuildChangeUint32ToSmi(base); 2168 inputs[1] = BuildChangeUint32ToSmi(base);
2163 inputs[2] = BuildChangeUint32ToSmi(length); 2169 inputs[2] = BuildChangeUint32ToSmi(length);
2164 inputs[3] = BuildChangeUint32ToSmi(index); 2170 inputs[3] = BuildChangeUint32ToSmi(index);
2165 inputs[4] = FunctionTable(); 2171 inputs[4] = FunctionTable(0);
2166 inputs[5] = Uint32Constant(sig_index); 2172 inputs[5] = Uint32Constant(sig_index);
2167 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count)); 2173 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count));
2168 2174
2169 // Pass in parameters and return types in to the runtime function 2175 // Pass in parameters and return types in to the runtime function
2170 // to allow it to regenerate signature 2176 // to allow it to regenerate signature
2171 for (uint32_t i = 0; i < return_count; ++i) { 2177 for (uint32_t i = 0; i < return_count; ++i) {
2172 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi( 2178 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi(
2173 Uint32Constant(static_cast<int>(sig->GetReturn(i)))); 2179 Uint32Constant(static_cast<int>(sig->GetReturn(i))));
2174 } 2180 }
2175 2181
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 2803 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
2798 } 2804 }
2799 } 2805 }
2800 2806
2801 Node* WasmGraphBuilder::DefaultS128Value() { 2807 Node* WasmGraphBuilder::DefaultS128Value() {
2802 Node* zero = jsgraph()->Int32Constant(0); 2808 Node* zero = jsgraph()->Int32Constant(0);
2803 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero, 2809 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero,
2804 zero, zero); 2810 zero, zero);
2805 } 2811 }
2806 2812
2807 Node* WasmGraphBuilder::FunctionTable() { 2813 Node* WasmGraphBuilder::FunctionTable(uint32_t index) {
2808 DCHECK(module_ && module_->instance && 2814 DCHECK(module_ && module_->instance &&
2809 !module_->instance->function_table.is_null()); 2815 index < module_->instance->function_tables.size());
2810 if (!function_table_) { 2816 if (index >= function_tables_.size()) {
Mircea Trofin 2016/07/26 03:37:26 I think it'd be a bit more readable if you either:
ddchen 2016/07/26 05:44:43 I'll take the former approach; the module isn't av
2811 function_table_ = HeapConstant(module_->instance->function_table); 2817 for (size_t i = function_tables_.size(); i <= index; i++) {
Mircea Trofin 2016/07/26 03:37:26 ++i
ddchen 2016/07/26 05:44:44 Done.
2818 DCHECK(!module_->instance->function_tables[i].is_null());
2819 function_tables_.push_back(
2820 HeapConstant(module_->instance->function_tables[i]));
2821 }
2812 } 2822 }
2813 return function_table_; 2823 return function_tables_[index];
2814 } 2824 }
2815 2825
2816 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node, 2826 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node,
2817 Runtime::FunctionId function_id, 2827 Runtime::FunctionId function_id,
2818 Signature<Conversion>* signature) { 2828 Signature<Conversion>* signature) {
2819 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); 2829 SimplifiedOperatorBuilder simplified(jsgraph()->zone());
2820 const Runtime::Function* function = Runtime::FunctionForId(function_id); 2830 const Runtime::Function* function = Runtime::FunctionForId(function_id);
2821 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 2831 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
2822 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties, 2832 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties,
2823 CallDescriptor::kNoFlags); 2833 CallDescriptor::kNoFlags);
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 function_->code_start_offset), 3474 function_->code_start_offset),
3465 compile_ms); 3475 compile_ms);
3466 } 3476 }
3467 3477
3468 return code; 3478 return code;
3469 } 3479 }
3470 3480
3471 } // namespace compiler 3481 } // namespace compiler
3472 } // namespace internal 3482 } // namespace internal
3473 } // namespace v8 3483 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698