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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 Node** buf = Realloc(effects, count, count + 1); | 354 Node** buf = Realloc(effects, count, count + 1); |
| 355 buf[count] = control; | 355 buf[count] = control; |
| 356 return graph()->NewNode(jsgraph()->common()->EffectPhi(count), count + 1, | 356 return graph()->NewNode(jsgraph()->common()->EffectPhi(count), count + 1, |
| 357 buf); | 357 buf); |
| 358 } | 358 } |
| 359 | 359 |
| 360 Node* WasmGraphBuilder::NumberConstant(int32_t value) { | 360 Node* WasmGraphBuilder::NumberConstant(int32_t value) { |
| 361 return jsgraph()->Constant(value); | 361 return jsgraph()->Constant(value); |
| 362 } | 362 } |
| 363 | 363 |
| 364 Node* WasmGraphBuilder::Uint32Constant(uint32_t value) { | |
| 365 return jsgraph()->Uint32Constant(value); | |
| 366 } | |
| 367 | |
| 364 Node* WasmGraphBuilder::Int32Constant(int32_t value) { | 368 Node* WasmGraphBuilder::Int32Constant(int32_t value) { |
| 365 return jsgraph()->Int32Constant(value); | 369 return jsgraph()->Int32Constant(value); |
| 366 } | 370 } |
| 367 | 371 |
| 368 Node* WasmGraphBuilder::Int64Constant(int64_t value) { | 372 Node* WasmGraphBuilder::Int64Constant(int64_t value) { |
| 369 return jsgraph()->Int64Constant(value); | 373 return jsgraph()->Int64Constant(value); |
| 370 } | 374 } |
| 371 | 375 |
| 372 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, | 376 Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, |
| 373 wasm::WasmCodePosition position) { | 377 wasm::WasmCodePosition position) { |
| (...skipping 1713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2087 graph()->NewNode(machine->Word32Shl(), key, | 2091 graph()->NewNode(machine->Word32Shl(), key, |
| 2088 Int32Constant(kPointerSizeLog2)), | 2092 Int32Constant(kPointerSizeLog2)), |
| 2089 Int32Constant(offset)), | 2093 Int32Constant(offset)), |
| 2090 *effect_, *control_); | 2094 *effect_, *control_); |
| 2091 | 2095 |
| 2092 args[0] = load_code; | 2096 args[0] = load_code; |
| 2093 wasm::FunctionSig* sig = module_->GetSignature(index); | 2097 wasm::FunctionSig* sig = module_->GetSignature(index); |
| 2094 return BuildWasmCall(sig, args, position); | 2098 return BuildWasmCall(sig, args, position); |
| 2095 } | 2099 } |
| 2096 | 2100 |
| 2101 Node* WasmGraphBuilder::JITSingleFunction(Node* const base, Node* const length, | |
|
titzer
2016/07/14 08:59:43
This should have been named BuildXXX, since it bui
ritesht
2016/07/14 18:10:00
I think in this module, they don't seem to use "Bu
| |
| 2102 Node* const index, | |
| 2103 const uint32_t sig_index, | |
| 2104 wasm::FunctionSig* const sig, | |
| 2105 wasm::WasmCodePosition position) { | |
| 2106 MachineOperatorBuilder* machine = jsgraph()->machine(); | |
| 2107 // Bounds check the memory access | |
| 2108 { | |
| 2109 Node* base_negative = | |
| 2110 graph()->NewNode(machine->Uint32LessThan(), base, Int32Constant(0)); | |
| 2111 trap_->AddTrapIfTrue(wasm::kTrapMemOutOfBounds, base_negative, position); | |
| 2112 | |
| 2113 Node* length_negative = graph()->NewNode(machine->Uint32LessThanOrEqual(), | |
| 2114 length, Int32Constant(0)); | |
| 2115 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position); | |
| 2116 | |
| 2117 Node* in_bounds = graph()->NewNode( | |
| 2118 machine->Uint32LessThanOrEqual(), | |
| 2119 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0)); | |
| 2120 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position); | |
| 2121 } | |
| 2122 | |
| 2123 // Bounds check the index. | |
| 2124 { | |
| 2125 int table_size = static_cast<int>(module_->FunctionTableSize()); | |
| 2126 if (table_size > 0) { | |
| 2127 // Bounds check against the table size. | |
| 2128 Node* size = Int32Constant(static_cast<int>(table_size)); | |
| 2129 Node* in_bounds = | |
| 2130 graph()->NewNode(machine->Uint32LessThan(), index, size); | |
| 2131 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position); | |
| 2132 } else { | |
| 2133 // No function table. Generate a trap and return a constant. | |
| 2134 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); | |
| 2135 return trap_->GetTrapValue(module_->GetSignature(sig_index)); | |
| 2136 } | |
| 2137 } | |
| 2138 | |
| 2139 const size_t runtime_input_params = 7; | |
| 2140 const size_t runtime_env_params = 5; | |
| 2141 | |
| 2142 Runtime::FunctionId f = Runtime::kJITSingleFunction; | |
| 2143 const Runtime::Function* fun = Runtime::FunctionForId(f); | |
| 2144 // CEntryStubConstant nodes have to be created and cached in the main | |
| 2145 // thread. At the moment this is only done for CEntryStubConstant(1). | |
| 2146 DCHECK_EQ(1, fun->result_size); | |
| 2147 const uint32_t return_count = static_cast<uint32_t>(sig->return_count()); | |
| 2148 const uint32_t parameter_count = | |
| 2149 static_cast<uint32_t>(sig->parameter_count()); | |
| 2150 | |
| 2151 const uint32_t inputs_size = runtime_input_params + runtime_env_params + | |
| 2152 return_count + parameter_count; | |
| 2153 Node** inputs = Buffer(inputs_size); | |
| 2154 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size); | |
| 2155 inputs[1] = BuildChangeUint32ToSmi(base); | |
| 2156 inputs[2] = BuildChangeUint32ToSmi(length); | |
| 2157 inputs[3] = BuildChangeUint32ToSmi(index); | |
| 2158 inputs[4] = FunctionTable(); | |
| 2159 inputs[5] = Uint32Constant(sig_index); | |
| 2160 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count)); | |
| 2161 | |
| 2162 // Pass in parameters and return types in to the runtime function | |
| 2163 // to allow it to regenerate signature | |
| 2164 for (uint32_t i = 0; i < return_count; ++i) { | |
| 2165 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi( | |
| 2166 Uint32Constant(static_cast<int>(sig->GetReturn(i)))); | |
| 2167 } | |
| 2168 | |
| 2169 for (uint32_t i = 0; i < parameter_count; ++i) { | |
| 2170 inputs[i + runtime_input_params + return_count] = BuildChangeUint32ToSmi( | |
| 2171 Uint32Constant(static_cast<int>(sig->GetParam(i)))); | |
| 2172 } | |
| 2173 | |
| 2174 const uint32_t args_offset = inputs_size - runtime_env_params; | |
| 2175 inputs[args_offset] = jsgraph()->ExternalConstant( | |
| 2176 ExternalReference(f, jsgraph()->isolate())); // ref | |
| 2177 inputs[args_offset + 1] = jsgraph()->Int32Constant(args_offset - 1); // arity | |
| 2178 inputs[args_offset + 2] = | |
| 2179 HeapConstant(module_->instance->context); // context | |
| 2180 inputs[args_offset + 3] = *effect_; | |
| 2181 inputs[args_offset + 4] = *control_; | |
| 2182 | |
| 2183 // Use the module context to call the runtime. | |
| 2184 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | |
| 2185 jsgraph()->zone(), f, args_offset - 1, Operator::kNoProperties, | |
| 2186 CallDescriptor::kNoFlags); | |
| 2187 | |
| 2188 Node* node = | |
| 2189 graph()->NewNode(jsgraph()->common()->Call(desc), inputs_size, inputs); | |
| 2190 *control_ = node; | |
| 2191 *effect_ = node; | |
| 2192 return node; | |
| 2193 } | |
| 2194 | |
| 2097 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { | 2195 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { |
| 2098 // Implement Rol by Ror since TurboFan does not have Rol opcode. | 2196 // Implement Rol by Ror since TurboFan does not have Rol opcode. |
| 2099 // TODO(weiliang): support Word32Rol opcode in TurboFan. | 2197 // TODO(weiliang): support Word32Rol opcode in TurboFan. |
| 2100 Int32Matcher m(right); | 2198 Int32Matcher m(right); |
| 2101 if (m.HasValue()) { | 2199 if (m.HasValue()) { |
| 2102 return Binop(wasm::kExprI32Ror, left, | 2200 return Binop(wasm::kExprI32Ror, left, |
| 2103 jsgraph()->Int32Constant(32 - m.Value())); | 2201 jsgraph()->Int32Constant(32 - m.Value())); |
| 2104 } else { | 2202 } else { |
| 2105 return Binop(wasm::kExprI32Ror, left, | 2203 return Binop(wasm::kExprI32Ror, left, |
| 2106 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right)); | 2204 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right)); |
| (...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3443 function_->code_start_offset), | 3541 function_->code_start_offset), |
| 3444 compile_ms); | 3542 compile_ms); |
| 3445 } | 3543 } |
| 3446 | 3544 |
| 3447 return code; | 3545 return code; |
| 3448 } | 3546 } |
| 3449 | 3547 |
| 3450 } // namespace compiler | 3548 } // namespace compiler |
| 3451 } // namespace internal | 3549 } // namespace internal |
| 3452 } // namespace v8 | 3550 } // namespace v8 |
| OLD | NEW |