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 <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 | 10 |
| (...skipping 2212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2223 | 2223 |
| 2224 // Allocate the box for the {value}. | 2224 // Allocate the box for the {value}. |
| 2225 vbox = BuildAllocateHeapNumberWithValue(value, if_box); | 2225 vbox = BuildAllocateHeapNumberWithValue(value, if_box); |
| 2226 | 2226 |
| 2227 Node* control = graph()->NewNode(common->Merge(2), if_smi, if_box); | 2227 Node* control = graph()->NewNode(common->Merge(2), if_smi, if_box); |
| 2228 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi, | 2228 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi, |
| 2229 vbox, control); | 2229 vbox, control); |
| 2230 return value; | 2230 return value; |
| 2231 } | 2231 } |
| 2232 | 2232 |
| 2233 Node* WasmGraphBuilder::ToJS(Node* node, wasm::LocalType type) { | 2233 Node* WasmGraphBuilder::ToJS(Node* node, Handle<Context> context, |
| 2234 wasm::LocalType type) { | |
| 2234 switch (type) { | 2235 switch (type) { |
| 2235 case wasm::kAstI32: | 2236 case wasm::kAstI32: |
| 2236 return BuildChangeInt32ToTagged(node); | 2237 return BuildChangeInt32ToTagged(node); |
| 2237 case wasm::kAstI64: | 2238 case wasm::kAstI64: |
| 2238 DCHECK(module_ && !module_->instance->context.is_null()); | |
| 2239 // Throw a TypeError. | 2239 // Throw a TypeError. |
| 2240 return BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(), | 2240 return BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(), |
| 2241 module_->instance->context, nullptr, 0, effect_, | 2241 context, nullptr, 0, effect_, *control_); |
| 2242 *control_); | |
| 2243 case wasm::kAstF32: | 2242 case wasm::kAstF32: |
| 2244 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(), | 2243 node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(), |
| 2245 node); | 2244 node); |
| 2246 return BuildChangeFloat64ToTagged(node); | 2245 return BuildChangeFloat64ToTagged(node); |
| 2247 case wasm::kAstF64: | 2246 case wasm::kAstF64: |
| 2248 return BuildChangeFloat64ToTagged(node); | 2247 return BuildChangeFloat64ToTagged(node); |
| 2249 case wasm::kAstStmt: | 2248 case wasm::kAstStmt: |
| 2250 return jsgraph()->UndefinedConstant(); | 2249 return jsgraph()->UndefinedConstant(); |
| 2251 default: | 2250 default: |
| 2252 UNREACHABLE(); | 2251 UNREACHABLE(); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2496 Node* WasmGraphBuilder::BuildLoadHeapNumberValue(Node* value, Node* control) { | 2495 Node* WasmGraphBuilder::BuildLoadHeapNumberValue(Node* value, Node* control) { |
| 2497 return graph()->NewNode(jsgraph()->machine()->Load(MachineType::Float64()), | 2496 return graph()->NewNode(jsgraph()->machine()->Load(MachineType::Float64()), |
| 2498 value, BuildHeapNumberValueIndexConstant(), | 2497 value, BuildHeapNumberValueIndexConstant(), |
| 2499 graph()->start(), control); | 2498 graph()->start(), control); |
| 2500 } | 2499 } |
| 2501 | 2500 |
| 2502 Node* WasmGraphBuilder::BuildHeapNumberValueIndexConstant() { | 2501 Node* WasmGraphBuilder::BuildHeapNumberValueIndexConstant() { |
| 2503 return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag); | 2502 return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag); |
| 2504 } | 2503 } |
| 2505 | 2504 |
| 2506 void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, | 2505 void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Context> context, |
| 2506 Handle<Code> wasm_code, | |
| 2507 wasm::FunctionSig* sig) { | 2507 wasm::FunctionSig* sig) { |
| 2508 int wasm_count = static_cast<int>(sig->parameter_count()); | 2508 int wasm_count = static_cast<int>(sig->parameter_count()); |
| 2509 int param_count; | 2509 int param_count; |
| 2510 if (jsgraph()->machine()->Is64()) { | 2510 if (jsgraph()->machine()->Is64()) { |
| 2511 param_count = static_cast<int>(sig->parameter_count()); | 2511 param_count = static_cast<int>(sig->parameter_count()); |
| 2512 } else { | 2512 } else { |
| 2513 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); | 2513 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); |
| 2514 } | 2514 } |
| 2515 int count = param_count + 3; | 2515 int count = param_count + 3; |
| 2516 Node** args = Buffer(count); | 2516 Node** args = Buffer(count); |
| 2517 | 2517 |
| 2518 // Build the start and the JS parameter nodes. | 2518 // Build the start and the JS parameter nodes. |
| 2519 Node* start = Start(param_count + 5); | 2519 Node* start = Start(param_count + 5); |
| 2520 *control_ = start; | 2520 *control_ = start; |
| 2521 *effect_ = start; | 2521 *effect_ = start; |
| 2522 // Create the context parameter | 2522 // Create the context parameter |
| 2523 Node* context = graph()->NewNode( | 2523 Node* context_node = graph()->NewNode( |
| 2524 jsgraph()->common()->Parameter( | 2524 jsgraph()->common()->Parameter( |
| 2525 Linkage::GetJSCallContextParamIndex(wasm_count + 1), "%context"), | 2525 Linkage::GetJSCallContextParamIndex(wasm_count + 1), "%context"), |
| 2526 graph()->start()); | 2526 graph()->start()); |
| 2527 | 2527 |
| 2528 int pos = 0; | 2528 int pos = 0; |
| 2529 args[pos++] = HeapConstant(wasm_code); | 2529 args[pos++] = HeapConstant(wasm_code); |
| 2530 | 2530 |
| 2531 // Convert JS parameters to WASM numbers. | 2531 // Convert JS parameters to WASM numbers. |
| 2532 for (int i = 0; i < wasm_count; ++i) { | 2532 for (int i = 0; i < wasm_count; ++i) { |
| 2533 Node* param = | 2533 Node* param = |
| 2534 graph()->NewNode(jsgraph()->common()->Parameter(i + 1), start); | 2534 graph()->NewNode(jsgraph()->common()->Parameter(i + 1), start); |
| 2535 Node* wasm_param = FromJS(param, context, sig->GetParam(i)); | 2535 Node* wasm_param = FromJS(param, context_node, sig->GetParam(i)); |
| 2536 args[pos++] = wasm_param; | 2536 args[pos++] = wasm_param; |
| 2537 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | 2537 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
| 2538 // We make up the high word with SAR to get the proper sign extension. | 2538 // We make up the high word with SAR to get the proper sign extension. |
| 2539 args[pos++] = graph()->NewNode(jsgraph()->machine()->Word32Sar(), | 2539 args[pos++] = graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
| 2540 wasm_param, jsgraph()->Int32Constant(31)); | 2540 wasm_param, jsgraph()->Int32Constant(31)); |
| 2541 } | 2541 } |
| 2542 } | 2542 } |
| 2543 | 2543 |
| 2544 args[pos++] = *effect_; | 2544 args[pos++] = *effect_; |
| 2545 args[pos++] = *control_; | 2545 args[pos++] = *control_; |
| 2546 | 2546 |
| 2547 // Call the WASM code. | 2547 // Call the WASM code. |
| 2548 CallDescriptor* desc = | 2548 CallDescriptor* desc = |
| 2549 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); | 2549 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); |
| 2550 if (jsgraph()->machine()->Is32()) { | 2550 if (jsgraph()->machine()->Is32()) { |
| 2551 desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc); | 2551 desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc); |
| 2552 } | 2552 } |
| 2553 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); | 2553 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); |
| 2554 Node* retval = call; | 2554 Node* retval = call; |
| 2555 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 2555 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
| 2556 sig->GetReturn(0) == wasm::kAstI64) { | 2556 sig->GetReturn(0) == wasm::kAstI64) { |
| 2557 // The return values comes as two values, we pick the low word. | 2557 // The return values comes as two values, we pick the low word. |
| 2558 retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval, | 2558 retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval, |
| 2559 graph()->start()); | 2559 graph()->start()); |
| 2560 } | 2560 } |
| 2561 Node* jsval = ToJS( | 2561 Node* jsval = |
| 2562 retval, sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2562 ToJS(retval, context, |
|
titzer
2016/08/22 08:28:14
Maybe this take a context_node, since we already h
| |
| 2563 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | |
| 2563 Node* ret = | 2564 Node* ret = |
| 2564 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); | 2565 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
| 2565 | 2566 |
| 2566 MergeControlToEnd(jsgraph(), ret); | 2567 MergeControlToEnd(jsgraph(), ret); |
| 2567 } | 2568 } |
| 2568 | 2569 |
| 2569 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<Context> context, | 2570 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<Context> context, |
| 2570 Handle<JSReceiver> target, | 2571 Handle<JSReceiver> target, |
| 2571 wasm::FunctionSig* sig) { | 2572 wasm::FunctionSig* sig) { |
| 2572 DCHECK(target->IsCallable()); | 2573 DCHECK(target->IsCallable()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2630 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | 2631 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), |
| 2631 callable.descriptor(), wasm_count + 1, | 2632 callable.descriptor(), wasm_count + 1, |
| 2632 CallDescriptor::kNoFlags); | 2633 CallDescriptor::kNoFlags); |
| 2633 } | 2634 } |
| 2634 | 2635 |
| 2635 // Convert WASM numbers to JS values. | 2636 // Convert WASM numbers to JS values. |
| 2636 int param_index = 0; | 2637 int param_index = 0; |
| 2637 for (int i = 0; i < wasm_count; ++i) { | 2638 for (int i = 0; i < wasm_count; ++i) { |
| 2638 Node* param = | 2639 Node* param = |
| 2639 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); | 2640 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); |
| 2640 args[pos++] = ToJS(param, sig->GetParam(i)); | 2641 args[pos++] = ToJS(param, context, sig->GetParam(i)); |
| 2641 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | 2642 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
| 2642 // On 32 bit platforms we have to skip the high word of int64 parameters. | 2643 // On 32 bit platforms we have to skip the high word of int64 parameters. |
| 2643 param_index++; | 2644 param_index++; |
| 2644 } | 2645 } |
| 2645 } | 2646 } |
| 2646 | 2647 |
| 2647 if (call_direct) { | 2648 if (call_direct) { |
| 2648 args[pos++] = jsgraph()->UndefinedConstant(); // new target | 2649 args[pos++] = jsgraph()->UndefinedConstant(); // new target |
| 2649 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | 2650 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| 2650 } | 2651 } |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2933 Handle<String> name_str = | 2934 Handle<String> name_str = |
| 2934 isolate->factory()->NewStringFromAsciiChecked(buffer.start()); | 2935 isolate->factory()->NewStringFromAsciiChecked(buffer.start()); |
| 2935 Handle<String> script_str = | 2936 Handle<String> script_str = |
| 2936 isolate->factory()->NewStringFromAsciiChecked("(WASM)"); | 2937 isolate->factory()->NewStringFromAsciiChecked("(WASM)"); |
| 2937 Handle<SharedFunctionInfo> shared = | 2938 Handle<SharedFunctionInfo> shared = |
| 2938 isolate->factory()->NewSharedFunctionInfo(name_str, code, false); | 2939 isolate->factory()->NewSharedFunctionInfo(name_str, code, false); |
| 2939 PROFILE(isolate, CodeCreateEvent(tag, AbstractCode::cast(*code), *shared, | 2940 PROFILE(isolate, CodeCreateEvent(tag, AbstractCode::cast(*code), *shared, |
| 2940 *script_str, 0, 0)); | 2941 *script_str, 0, 0)); |
| 2941 } | 2942 } |
| 2942 | 2943 |
| 2943 Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, | 2944 Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, Handle<Context> context, |
| 2945 wasm::ModuleEnv* module, | |
| 2944 Handle<Code> wasm_code, uint32_t index) { | 2946 Handle<Code> wasm_code, uint32_t index) { |
| 2945 const wasm::WasmFunction* func = &module->module->functions[index]; | 2947 const wasm::WasmFunction* func = &module->module->functions[index]; |
| 2946 | 2948 |
| 2947 //---------------------------------------------------------------------------- | 2949 //---------------------------------------------------------------------------- |
| 2948 // Create the Graph | 2950 // Create the Graph |
| 2949 //---------------------------------------------------------------------------- | 2951 //---------------------------------------------------------------------------- |
| 2950 Zone zone(isolate->allocator()); | 2952 Zone zone(isolate->allocator()); |
| 2951 Graph graph(&zone); | 2953 Graph graph(&zone); |
| 2952 CommonOperatorBuilder common(&zone); | 2954 CommonOperatorBuilder common(&zone); |
| 2953 MachineOperatorBuilder machine(&zone); | 2955 MachineOperatorBuilder machine(&zone); |
| 2954 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 2956 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
| 2955 | 2957 |
| 2956 Node* control = nullptr; | 2958 Node* control = nullptr; |
| 2957 Node* effect = nullptr; | 2959 Node* effect = nullptr; |
| 2958 | 2960 |
| 2959 WasmGraphBuilder builder(&zone, &jsgraph, func->sig); | 2961 WasmGraphBuilder builder(&zone, &jsgraph, func->sig); |
| 2960 builder.set_control_ptr(&control); | 2962 builder.set_control_ptr(&control); |
| 2961 builder.set_effect_ptr(&effect); | 2963 builder.set_effect_ptr(&effect); |
| 2962 builder.set_module(module); | 2964 builder.set_module(module); |
| 2963 builder.BuildJSToWasmWrapper(wasm_code, func->sig); | 2965 builder.BuildJSToWasmWrapper(context, wasm_code, func->sig); |
| 2964 | 2966 |
| 2965 //---------------------------------------------------------------------------- | 2967 //---------------------------------------------------------------------------- |
| 2966 // Run the compilation pipeline. | 2968 // Run the compilation pipeline. |
| 2967 //---------------------------------------------------------------------------- | 2969 //---------------------------------------------------------------------------- |
| 2968 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 2970 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
| 2969 OFStream os(stdout); | 2971 OFStream os(stdout); |
| 2970 os << "-- Graph after change lowering -- " << std::endl; | 2972 os << "-- Graph after change lowering -- " << std::endl; |
| 2971 os << AsRPO(graph); | 2973 os << AsRPO(graph); |
| 2972 } | 2974 } |
| 2973 | 2975 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3272 function_->code_start_offset), | 3274 function_->code_start_offset), |
| 3273 compile_ms); | 3275 compile_ms); |
| 3274 } | 3276 } |
| 3275 | 3277 |
| 3276 return code; | 3278 return code; |
| 3277 } | 3279 } |
| 3278 | 3280 |
| 3279 } // namespace compiler | 3281 } // namespace compiler |
| 3280 } // namespace internal | 3282 } // namespace internal |
| 3281 } // namespace v8 | 3283 } // namespace v8 |
| OLD | NEW |