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 2686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2697 } | 2697 } |
2698 Node* jsval = | 2698 Node* jsval = |
2699 ToJS(retval, context, | 2699 ToJS(retval, context, |
2700 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2700 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
2701 Node* ret = | 2701 Node* ret = |
2702 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); | 2702 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
2703 | 2703 |
2704 MergeControlToEnd(jsgraph(), ret); | 2704 MergeControlToEnd(jsgraph(), ret); |
2705 } | 2705 } |
2706 | 2706 |
2707 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, | 2707 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
2708 wasm::FunctionSig* sig) { | 2708 wasm::FunctionSig* sig) { |
2709 int js_count = function->shared()->internal_formal_parameter_count(); | 2709 DCHECK(target->IsCallable()); |
2710 | |
2710 int wasm_count = static_cast<int>(sig->parameter_count()); | 2711 int wasm_count = static_cast<int>(sig->parameter_count()); |
2711 int param_count; | 2712 int param_count; |
2712 if (jsgraph()->machine()->Is64()) { | 2713 if (jsgraph()->machine()->Is64()) { |
2713 param_count = wasm_count; | 2714 param_count = wasm_count; |
2714 } else { | 2715 } else { |
2715 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); | 2716 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); |
2716 } | 2717 } |
2717 | 2718 |
2718 // Build the start and the parameter nodes. | 2719 // Build the start and the parameter nodes. |
2719 Isolate* isolate = jsgraph()->isolate(); | 2720 Isolate* isolate = jsgraph()->isolate(); |
2720 CallDescriptor* desc; | 2721 CallDescriptor* desc; |
2721 Node* start = Start(param_count + 3); | 2722 Node* start = Start(param_count + 3); |
2722 *effect_ = start; | 2723 *effect_ = start; |
2723 *control_ = start; | 2724 *control_ = start; |
2724 // JS context is the last parameter. | 2725 // JS context is the last parameter. |
2725 Node* context = HeapConstant(Handle<Context>(function->context(), isolate)); | 2726 Node* context = HeapConstant(isolate->native_context()); |
Benedikt Meurer
2016/08/03 17:14:43
Uhm, that looks weird. Are you really sure that th
ahaas
2016/08/09 14:34:54
Done.
| |
2726 Node** args = Buffer(wasm_count + 7); | 2727 Node** args = Buffer(wasm_count + 7); |
2727 | 2728 |
2728 bool arg_count_before_args = false; | 2729 bool arg_count_before_args = false; |
2729 bool add_new_target_undefined = false; | 2730 bool add_new_target_undefined = false; |
2730 | 2731 |
2731 int pos = 0; | 2732 int pos = 0; |
2732 if (js_count == wasm_count) { | 2733 |
2733 // exact arity match, just call the function directly. | 2734 // Use the Call builtin. |
titzer
2016/08/03 16:33:49
Always using the builtin does increase the overhea
ahaas
2016/08/09 14:34:54
I reintroduced this optimization now for the case
| |
2734 desc = Linkage::GetJSCallDescriptor(graph()->zone(), false, wasm_count + 1, | 2735 Callable callable = CodeFactory::Call(isolate); |
2736 args[pos++] = jsgraph()->HeapConstant(callable.code()); | |
2737 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | |
2738 callable.descriptor(), wasm_count + 1, | |
2735 CallDescriptor::kNoFlags); | 2739 CallDescriptor::kNoFlags); |
2736 arg_count_before_args = false; | 2740 arg_count_before_args = true; |
2737 add_new_target_undefined = true; | |
2738 } else { | |
2739 // Use the Call builtin. | |
2740 Callable callable = CodeFactory::Call(isolate); | |
2741 args[pos++] = jsgraph()->HeapConstant(callable.code()); | |
2742 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | |
2743 callable.descriptor(), wasm_count + 1, | |
2744 CallDescriptor::kNoFlags); | |
2745 arg_count_before_args = true; | |
2746 } | |
2747 | 2741 |
2748 args[pos++] = jsgraph()->Constant(function); // JS function. | 2742 args[pos++] = jsgraph()->Constant(target); // JS function. |
Benedikt Meurer
2016/08/03 17:14:43
Nit: Update comment.
ahaas
2016/08/09 14:34:54
Done.
| |
2749 if (arg_count_before_args) { | 2743 if (arg_count_before_args) { |
2750 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | 2744 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
2751 } | 2745 } |
2752 // Create the receiver constant (either undefined or the global proxy). | 2746 // Create the receiver constant (either undefined or the global proxy). |
2753 Handle<Object> receiver(isolate->heap()->undefined_value(), isolate); | 2747 Handle<Object> receiver(isolate->heap()->undefined_value(), isolate); |
2754 if (is_sloppy(function->shared()->language_mode())) { | |
2755 receiver = Handle<Object>(function->context()->global_proxy(), isolate); | |
2756 } | |
2757 args[pos++] = jsgraph()->Constant(receiver); | 2748 args[pos++] = jsgraph()->Constant(receiver); |
2758 | |
2759 // Convert WASM numbers to JS values. | 2749 // Convert WASM numbers to JS values. |
2760 int param_index = 0; | 2750 int param_index = 0; |
2761 for (int i = 0; i < wasm_count; ++i) { | 2751 for (int i = 0; i < wasm_count; ++i) { |
2762 Node* param = | 2752 Node* param = |
2763 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); | 2753 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); |
2764 args[pos++] = ToJS(param, context, sig->GetParam(i)); | 2754 args[pos++] = ToJS(param, context, sig->GetParam(i)); |
Benedikt Meurer
2016/08/03 17:14:43
The ToJS should be (and seems to be) completely co
| |
2765 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | 2755 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
2766 // On 32 bit platforms we have to skip the high word of int64 parameters. | 2756 // On 32 bit platforms we have to skip the high word of int64 parameters. |
2767 param_index++; | 2757 param_index++; |
2768 } | 2758 } |
2769 } | 2759 } |
2770 | 2760 |
2771 if (add_new_target_undefined) { | 2761 if (add_new_target_undefined) { |
2772 args[pos++] = jsgraph()->UndefinedConstant(); // new target | 2762 args[pos++] = jsgraph()->UndefinedConstant(); // new target |
2773 } | 2763 } |
2774 | 2764 |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3217 | 3207 |
3218 if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) { | 3208 if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) { |
3219 RecordFunctionCompilation( | 3209 RecordFunctionCompilation( |
3220 CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index, | 3210 CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index, |
3221 wasm::WasmName("export"), | 3211 wasm::WasmName("export"), |
3222 module->module->GetName(func->name_offset, func->name_length)); | 3212 module->module->GetName(func->name_offset, func->name_length)); |
3223 } | 3213 } |
3224 return code; | 3214 return code; |
3225 } | 3215 } |
3226 | 3216 |
3227 Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, | 3217 Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, |
3228 Handle<JSFunction> function, | |
3229 wasm::FunctionSig* sig, uint32_t index, | 3218 wasm::FunctionSig* sig, uint32_t index, |
3230 Handle<String> import_module, | 3219 Handle<String> import_module, |
3231 MaybeHandle<String> import_function) { | 3220 MaybeHandle<String> import_function) { |
3232 //---------------------------------------------------------------------------- | 3221 //---------------------------------------------------------------------------- |
3233 // Create the Graph | 3222 // Create the Graph |
3234 //---------------------------------------------------------------------------- | 3223 //---------------------------------------------------------------------------- |
3235 Zone zone(isolate->allocator()); | 3224 Zone zone(isolate->allocator()); |
3236 Graph graph(&zone); | 3225 Graph graph(&zone); |
3237 CommonOperatorBuilder common(&zone); | 3226 CommonOperatorBuilder common(&zone); |
3238 MachineOperatorBuilder machine(&zone); | 3227 MachineOperatorBuilder machine(&zone); |
3239 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3228 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
3240 | 3229 |
3241 Node* control = nullptr; | 3230 Node* control = nullptr; |
3242 Node* effect = nullptr; | 3231 Node* effect = nullptr; |
3243 | 3232 |
3244 WasmGraphBuilder builder(&zone, &jsgraph, sig); | 3233 WasmGraphBuilder builder(&zone, &jsgraph, sig); |
3245 builder.set_control_ptr(&control); | 3234 builder.set_control_ptr(&control); |
3246 builder.set_effect_ptr(&effect); | 3235 builder.set_effect_ptr(&effect); |
3247 builder.BuildWasmToJSWrapper(function, sig); | 3236 builder.BuildWasmToJSWrapper(target, sig); |
3248 | 3237 |
3249 Handle<Code> code = Handle<Code>::null(); | 3238 Handle<Code> code = Handle<Code>::null(); |
3250 { | 3239 { |
3251 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 3240 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
3252 OFStream os(stdout); | 3241 OFStream os(stdout); |
3253 os << "-- Graph after change lowering -- " << std::endl; | 3242 os << "-- Graph after change lowering -- " << std::endl; |
3254 os << AsRPO(graph); | 3243 os << AsRPO(graph); |
3255 } | 3244 } |
3256 | 3245 |
3257 // Schedule and compile to machine code. | 3246 // Schedule and compile to machine code. |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3496 function_->code_start_offset), | 3485 function_->code_start_offset), |
3497 compile_ms); | 3486 compile_ms); |
3498 } | 3487 } |
3499 | 3488 |
3500 return code; | 3489 return code; |
3501 } | 3490 } |
3502 | 3491 |
3503 } // namespace compiler | 3492 } // namespace compiler |
3504 } // namespace internal | 3493 } // namespace internal |
3505 } // namespace v8 | 3494 } // namespace v8 |
OLD | NEW |