Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |