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

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: Created 4 years, 5 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_table_(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 1761 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // Bounds check the index. 2060 // Bounds check the index.
2061 int table_size = static_cast<int>(module_->FunctionTableSize()); 2061 int table_size = 0;
2062 if (table_size > 0) { 2062 // Assume only one table for now.
ahaas 2016/07/25 19:23:44 Could you add a DCHECK for this assumption?
ddchen 2016/07/25 22:17:36 Done.
2063 if (module_->IsValidTable(0) &&
2064 ((table_size = module_->GetTable(0)->max_size) > 0)) {
ahaas 2016/07/25 19:23:44 I personally don't like assignments in conditions.
ddchen 2016/07/25 22:17:36 Done.
2063 // Bounds check against the table size. 2065 // Bounds check against the table size.
2064 Node* size = Int32Constant(static_cast<int>(table_size)); 2066 Node* size = Int32Constant(table_size);
2065 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); 2067 Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
2066 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position); 2068 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position);
2067 } else { 2069 } else {
2068 // No function table. Generate a trap and return a constant. 2070 // No function table. Generate a trap and return a constant.
2069 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2071 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2070 return trap_->GetTrapValue(module_->GetSignature(index)); 2072 return trap_->GetTrapValue(module_->GetSignature(index));
2071 } 2073 }
2072 Node* table = FunctionTable(); 2074 Node* table = FunctionTable(0);
2073 2075
2074 // Load signature from the table and check. 2076 // Load signature from the table and check.
2075 // The table is a FixedArray; signatures are encoded as SMIs. 2077 // The table is a FixedArray; signatures are encoded as SMIs.
2076 // [sig1, sig2, sig3, ...., code1, code2, code3 ...] 2078 // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
2077 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 2079 ElementAccess access = AccessBuilder::ForFixedArrayElement();
2078 const int fixed_offset = access.header_size - access.tag(); 2080 const int fixed_offset = access.header_size - access.tag();
2079 { 2081 {
2080 Node* load_sig = graph()->NewNode( 2082 Node* load_sig = graph()->NewNode(
2081 machine->Load(MachineType::AnyTagged()), table, 2083 machine->Load(MachineType::AnyTagged()), table,
2082 graph()->NewNode(machine->Int32Add(), 2084 graph()->NewNode(machine->Int32Add(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position); 2124 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position);
2123 2125
2124 Node* in_bounds = graph()->NewNode( 2126 Node* in_bounds = graph()->NewNode(
2125 machine->Uint32LessThanOrEqual(), 2127 machine->Uint32LessThanOrEqual(),
2126 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0)); 2128 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0));
2127 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position); 2129 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position);
2128 } 2130 }
2129 2131
2130 // Bounds check the index. 2132 // Bounds check the index.
2131 { 2133 {
2132 int table_size = static_cast<int>(module_->FunctionTableSize()); 2134 int table_size = 0;
2133 if (table_size > 0) { 2135 // Assume only one table for now.
ahaas 2016/07/25 19:23:44 same here.
ddchen 2016/07/25 22:17:36 Done.
2136 if (module_->IsValidTable(0) &&
2137 ((table_size = module_->GetTable(0)->max_size) > 0)) {
2134 // Bounds check against the table size. 2138 // Bounds check against the table size.
2135 Node* size = Int32Constant(static_cast<int>(table_size)); 2139 Node* size = Int32Constant(table_size);
2136 Node* in_bounds = 2140 Node* in_bounds =
2137 graph()->NewNode(machine->Uint32LessThan(), index, size); 2141 graph()->NewNode(machine->Uint32LessThan(), index, size);
2138 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position); 2142 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position);
2139 } else { 2143 } else {
2140 // No function table. Generate a trap and return a constant. 2144 // No function table. Generate a trap and return a constant.
2141 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); 2145 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position);
2142 return trap_->GetTrapValue(module_->GetSignature(sig_index)); 2146 return trap_->GetTrapValue(module_->GetSignature(sig_index));
2143 } 2147 }
2144 } 2148 }
2145 2149
2146 const size_t runtime_input_params = 7; 2150 const size_t runtime_input_params = 7;
2147 const size_t runtime_env_params = 5; 2151 const size_t runtime_env_params = 5;
2148 2152
2149 Runtime::FunctionId f = Runtime::kJITSingleFunction; 2153 Runtime::FunctionId f = Runtime::kJITSingleFunction;
2150 const Runtime::Function* fun = Runtime::FunctionForId(f); 2154 const Runtime::Function* fun = Runtime::FunctionForId(f);
2151 // CEntryStubConstant nodes have to be created and cached in the main 2155 // CEntryStubConstant nodes have to be created and cached in the main
2152 // thread. At the moment this is only done for CEntryStubConstant(1). 2156 // thread. At the moment this is only done for CEntryStubConstant(1).
2153 DCHECK_EQ(1, fun->result_size); 2157 DCHECK_EQ(1, fun->result_size);
2154 const uint32_t return_count = static_cast<uint32_t>(sig->return_count()); 2158 const uint32_t return_count = static_cast<uint32_t>(sig->return_count());
2155 const uint32_t parameter_count = 2159 const uint32_t parameter_count =
2156 static_cast<uint32_t>(sig->parameter_count()); 2160 static_cast<uint32_t>(sig->parameter_count());
2157 2161
2158 const uint32_t inputs_size = runtime_input_params + runtime_env_params + 2162 const uint32_t inputs_size = runtime_input_params + runtime_env_params +
2159 return_count + parameter_count; 2163 return_count + parameter_count;
2160 Node** inputs = Buffer(inputs_size); 2164 Node** inputs = Buffer(inputs_size);
2161 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size); 2165 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size);
2162 inputs[1] = BuildChangeUint32ToSmi(base); 2166 inputs[1] = BuildChangeUint32ToSmi(base);
2163 inputs[2] = BuildChangeUint32ToSmi(length); 2167 inputs[2] = BuildChangeUint32ToSmi(length);
2164 inputs[3] = BuildChangeUint32ToSmi(index); 2168 inputs[3] = BuildChangeUint32ToSmi(index);
2165 inputs[4] = FunctionTable(); 2169 inputs[4] = FunctionTable(0);
2166 inputs[5] = Uint32Constant(sig_index); 2170 inputs[5] = Uint32Constant(sig_index);
2167 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count)); 2171 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count));
2168 2172
2169 // Pass in parameters and return types in to the runtime function 2173 // Pass in parameters and return types in to the runtime function
2170 // to allow it to regenerate signature 2174 // to allow it to regenerate signature
2171 for (uint32_t i = 0; i < return_count; ++i) { 2175 for (uint32_t i = 0; i < return_count; ++i) {
2172 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi( 2176 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi(
2173 Uint32Constant(static_cast<int>(sig->GetReturn(i)))); 2177 Uint32Constant(static_cast<int>(sig->GetReturn(i))));
2174 } 2178 }
2175 2179
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE); 2801 size + offset, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
2798 } 2802 }
2799 } 2803 }
2800 2804
2801 Node* WasmGraphBuilder::DefaultS128Value() { 2805 Node* WasmGraphBuilder::DefaultS128Value() {
2802 Node* zero = jsgraph()->Int32Constant(0); 2806 Node* zero = jsgraph()->Int32Constant(0);
2803 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero, 2807 return graph()->NewNode(jsgraph()->machine()->CreateInt32x4(), zero, zero,
2804 zero, zero); 2808 zero, zero);
2805 } 2809 }
2806 2810
2807 Node* WasmGraphBuilder::FunctionTable() { 2811 Node* WasmGraphBuilder::FunctionTable(uint32_t index) {
2808 DCHECK(module_ && module_->instance && 2812 DCHECK(module_ && module_->instance &&
2809 !module_->instance->function_table.is_null()); 2813 index < module_->instance->function_table.size());
2810 if (!function_table_) { 2814 if (index >= function_table_.size()) {
2811 function_table_ = HeapConstant(module_->instance->function_table); 2815 for (uint32_t i = 0; i <= index; i++) {
2816 if (i < function_table_.size() && function_table_[i]) {
2817 continue;
2818 }
2819 DCHECK(!module_->instance->function_table[index].is_null());
ahaas 2016/07/25 19:23:44 Shouldn't this be {i} instead of {index}? If you r
2820 function_table_.push_back(
ahaas 2016/07/25 19:23:44 Does {push_back} actually add the element at the r
ddchen 2016/07/25 22:17:36 This code was incorrect, it should be fixed now.
2821 HeapConstant(module_->instance->function_table[index]));
2822 }
2812 } 2823 }
2813 return function_table_; 2824 return function_table_[index];
2814 } 2825 }
2815 2826
2816 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node, 2827 Node* WasmGraphBuilder::ChangeToRuntimeCall(Node* node,
2817 Runtime::FunctionId function_id, 2828 Runtime::FunctionId function_id,
2818 Signature<Conversion>* signature) { 2829 Signature<Conversion>* signature) {
2819 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); 2830 SimplifiedOperatorBuilder simplified(jsgraph()->zone());
2820 const Runtime::Function* function = Runtime::FunctionForId(function_id); 2831 const Runtime::Function* function = Runtime::FunctionForId(function_id);
2821 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( 2832 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
2822 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties, 2833 jsgraph()->zone(), function_id, function->nargs, Operator::kNoProperties,
2823 CallDescriptor::kNoFlags); 2834 CallDescriptor::kNoFlags);
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 function_->code_start_offset), 3475 function_->code_start_offset),
3465 compile_ms); 3476 compile_ms);
3466 } 3477 }
3467 3478
3468 return code; 3479 return code;
3469 } 3480 }
3470 3481
3471 } // namespace compiler 3482 } // namespace compiler
3472 } // namespace internal 3483 } // namespace internal
3473 } // namespace v8 3484 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698