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 <stdint.h> | 5 #include <stdint.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "src/base/utils/random-number-generator.h" | 9 #include "src/base/utils/random-number-generator.h" |
| 10 | 10 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 if (module == nullptr) { | 190 if (module == nullptr) { |
| 191 module = new WasmModule(); | 191 module = new WasmModule(); |
| 192 module->globals = nullptr; | 192 module->globals = nullptr; |
| 193 module->functions = nullptr; | 193 module->functions = nullptr; |
| 194 module->data_segments = nullptr; | 194 module->data_segments = nullptr; |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 }; | 197 }; |
| 198 | 198 |
| 199 | 199 |
| 200 static void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, FunctionEnv* env, | |
| 201 const byte* start, const byte* end) { | |
| 202 compiler::WasmGraphBuilder builder(zone, jsgraph, env->sig); | |
| 203 TreeResult result = BuildTFGraph(&builder, env, start, end); | |
| 204 if (result.failed()) { | |
| 205 ptrdiff_t pc = result.error_pc - result.start; | |
| 206 ptrdiff_t pt = result.error_pt - result.start; | |
| 207 std::ostringstream str; | |
| 208 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
| 209 if (result.error_pt) str << ", pt = +" << pt; | |
| 210 str << ", msg = " << result.error_msg.get(); | |
| 211 FATAL(str.str().c_str()); | |
| 212 } | |
| 213 if (FLAG_trace_turbo_graph) { | |
| 214 OFStream os(stdout); | |
| 215 os << AsRPO(*jsgraph->graph()); | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 | |
| 200 // A helper for compiling functions that are only internally callable WASM code. | 220 // A helper for compiling functions that are only internally callable WASM code. |
| 201 class WasmFunctionCompiler : public HandleAndZoneScope, | 221 class WasmFunctionCompiler : public HandleAndZoneScope, |
| 202 private GraphAndBuilders { | 222 private GraphAndBuilders { |
| 203 public: | 223 public: |
| 204 explicit WasmFunctionCompiler(FunctionSig* sig) | 224 explicit WasmFunctionCompiler(FunctionSig* sig) |
| 205 : GraphAndBuilders(main_zone()), | 225 : GraphAndBuilders(main_zone()), |
| 206 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, | 226 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, |
| 207 nullptr, this->machine()), | 227 nullptr, this->machine()), |
| 208 descriptor_(nullptr) { | 228 descriptor_(nullptr) { |
| 209 init_env(&env, sig); | 229 init_env(&env, sig); |
| 210 } | 230 } |
| 211 | 231 |
| 212 JSGraph jsgraph; | 232 JSGraph jsgraph; |
| 213 FunctionEnv env; | 233 FunctionEnv env; |
| 214 // The call descriptor is initialized when the function is compiled. | 234 // The call descriptor is initialized when the function is compiled. |
| 215 CallDescriptor* descriptor_; | 235 CallDescriptor* descriptor_; |
| 216 | 236 |
| 217 Isolate* isolate() { return main_isolate(); } | 237 Isolate* isolate() { return main_isolate(); } |
| 218 Graph* graph() const { return main_graph_; } | 238 Graph* graph() const { return main_graph_; } |
| 219 Zone* zone() const { return graph()->zone(); } | 239 Zone* zone() const { return graph()->zone(); } |
| 220 CommonOperatorBuilder* common() { return &main_common_; } | 240 CommonOperatorBuilder* common() { return &main_common_; } |
| 221 MachineOperatorBuilder* machine() { return &main_machine_; } | 241 MachineOperatorBuilder* machine() { return &main_machine_; } |
| 222 CallDescriptor* descriptor() { return descriptor_; } | 242 CallDescriptor* descriptor() { return descriptor_; } |
| 223 | 243 |
| 224 void Build(const byte* start, const byte* end) { | 244 void Build(const byte* start, const byte* end) { |
| 225 compiler::WasmGraphBuilder builder(main_zone(), &jsgraph, env.sig); | 245 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); |
| 226 TreeResult result = BuildTFGraph(&builder, &env, start, end); | |
| 227 if (result.failed()) { | |
| 228 ptrdiff_t pc = result.error_pc - result.start; | |
| 229 ptrdiff_t pt = result.error_pt - result.start; | |
| 230 std::ostringstream str; | |
| 231 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
| 232 if (result.error_pt) str << ", pt = +" << pt; | |
| 233 str << ", msg = " << result.error_msg.get(); | |
| 234 FATAL(str.str().c_str()); | |
| 235 } | |
| 236 if (FLAG_trace_turbo_graph) { | |
| 237 OFStream os(stdout); | |
| 238 os << AsRPO(*jsgraph.graph()); | |
| 239 } | |
| 240 } | 246 } |
| 241 | 247 |
| 242 byte AllocateLocal(LocalType type) { | 248 byte AllocateLocal(LocalType type) { |
| 243 int result = static_cast<int>(env.total_locals); | 249 int result = static_cast<int>(env.total_locals); |
| 244 env.AddLocals(type, 1); | 250 env.AddLocals(type, 1); |
| 245 byte b = static_cast<byte>(result); | 251 byte b = static_cast<byte>(result); |
| 246 CHECK_EQ(result, b); | 252 CHECK_EQ(result, b); |
| 247 return b; | 253 return b; |
| 248 } | 254 } |
| 249 | 255 |
| (...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2288 | 2294 |
| 2289 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { | 2295 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { |
| 2290 WasmRunner<int32_t> r(MachineType::Int32()); | 2296 WasmRunner<int32_t> r(MachineType::Int32()); |
| 2291 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), | 2297 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), |
| 2292 WASM_INFINITE_LOOP)); | 2298 WASM_INFINITE_LOOP)); |
| 2293 // Run the code, but don't go into the infinite loop. | 2299 // Run the code, but don't go into the infinite loop. |
| 2294 CHECK_EQ(45, r.Call(1)); | 2300 CHECK_EQ(45, r.Call(1)); |
| 2295 } | 2301 } |
| 2296 | 2302 |
| 2297 | 2303 |
| 2298 // TODO(titzer): Fix for nosee4 and re-enable. | 2304 static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { |
| 2299 #if 0 | 2305 if (!WasmOpcodes::IsSupported(opcode)) return; |
| 2300 | 2306 |
| 2301 static void TestBuildGraphForUnop(WasmOpcode opcode, FunctionSig* sig) { | 2307 Zone zone; |
| 2302 WasmRunner<int32_t> r(MachineType::Int32()); | 2308 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 2303 init_env(r.env(), sig); | 2309 HandleScope scope(isolate); |
| 2304 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0); | 2310 // Enable all optional operators. |
| 2305 } | 2311 CommonOperatorBuilder common(&zone); |
| 2312 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), | |
| 2313 MachineOperatorBuilder::kAllOptionalOps); | |
| 2314 Graph graph(&zone); | |
| 2315 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | |
| 2316 FunctionEnv env; | |
| 2317 FunctionSig* sig = WasmOpcodes::Signature(opcode); | |
| 2318 init_env(&env, sig); | |
| 2306 | 2319 |
| 2307 | 2320 if (sig->parameter_count() == 1) { |
| 2308 static void TestBuildGraphForBinop(WasmOpcode opcode, FunctionSig* sig) { | 2321 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0}; |
| 2309 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); | 2322 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); |
| 2310 init_env(r.env(), sig); | 2323 } else { |
|
Michael Starzinger
2016/01/07 14:44:34
suggestion: Would a DCHECK_EQ(2, sig->parameter_co
| |
| 2311 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, 1); | 2324 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, |
| 2325 1}; | |
| 2326 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); | |
| 2327 } | |
| 2312 } | 2328 } |
| 2313 | 2329 |
| 2314 | 2330 |
| 2315 TEST(Build_Wasm_SimpleExprs) { | 2331 TEST(Build_Wasm_SimpleExprs) { |
| 2316 // Test that the decoder can build a graph for all supported simple expressions. | 2332 // Test that the decoder can build a graph for all supported simple expressions. |
| 2317 #define GRAPH_BUILD_TEST(name, opcode, sig) \ | 2333 #define GRAPH_BUILD_TEST(name, opcode, sig) \ |
| 2318 if (WasmOpcodes::IsSupported(kExpr##name)) { \ | 2334 TestBuildGraphForSimpleExpression(kExpr##name); |
| 2319 FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \ | |
| 2320 printf("expression: " #name "\n"); \ | |
| 2321 if (sig->parameter_count() == 1) { \ | |
| 2322 TestBuildGraphForUnop(kExpr##name, sig); \ | |
| 2323 } else { \ | |
| 2324 TestBuildGraphForBinop(kExpr##name, sig); \ | |
| 2325 } \ | |
| 2326 } | |
| 2327 | 2335 |
| 2328 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); | 2336 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); |
| 2329 | 2337 |
| 2330 #undef GRAPH_BUILD_TEST | 2338 #undef GRAPH_BUILD_TEST |
| 2331 } | 2339 } |
| 2332 | 2340 |
| 2333 #endif | |
| 2334 | |
| 2335 | 2341 |
| 2336 TEST(Run_Wasm_Int32LoadInt8_signext) { | 2342 TEST(Run_Wasm_Int32LoadInt8_signext) { |
| 2337 TestingModule module; | 2343 TestingModule module; |
| 2338 const int kNumElems = 16; | 2344 const int kNumElems = 16; |
| 2339 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); | 2345 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); |
| 2340 module.RandomizeMemory(); | 2346 module.RandomizeMemory(); |
| 2341 memory[0] = -1; | 2347 memory[0] = -1; |
| 2342 WasmRunner<int32_t> r(MachineType::Int32()); | 2348 WasmRunner<int32_t> r(MachineType::Int32()); |
| 2343 r.env()->module = &module; | 2349 r.env()->module = &module; |
| 2344 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); | 2350 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3567 TEST(Run_Wasm_F32CopySign) { | 3573 TEST(Run_Wasm_F32CopySign) { |
| 3568 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); | 3574 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); |
| 3569 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 3575 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 3570 | 3576 |
| 3571 FOR_FLOAT32_INPUTS(i) { | 3577 FOR_FLOAT32_INPUTS(i) { |
| 3572 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } | 3578 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } |
| 3573 } | 3579 } |
| 3574 } | 3580 } |
| 3575 | 3581 |
| 3576 #endif | 3582 #endif |
| OLD | NEW |