Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(858)

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 2619803004: [wasm] Add support for compiling WASM_INTERPRETER_ENTRY stubs (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 18 matching lines...) Expand all
29 #include "src/compiler/zone-stats.h" 29 #include "src/compiler/zone-stats.h"
30 30
31 #include "src/code-factory.h" 31 #include "src/code-factory.h"
32 #include "src/code-stubs.h" 32 #include "src/code-stubs.h"
33 #include "src/factory.h" 33 #include "src/factory.h"
34 #include "src/log-inl.h" 34 #include "src/log-inl.h"
35 35
36 #include "src/wasm/function-body-decoder.h" 36 #include "src/wasm/function-body-decoder.h"
37 #include "src/wasm/wasm-limits.h" 37 #include "src/wasm/wasm-limits.h"
38 #include "src/wasm/wasm-module.h" 38 #include "src/wasm/wasm-module.h"
39 #include "src/wasm/wasm-objects.h"
39 #include "src/wasm/wasm-opcodes.h" 40 #include "src/wasm/wasm-opcodes.h"
40 #include "src/wasm/wasm-text.h" 41 #include "src/wasm/wasm-text.h"
41 42
42 // TODO(titzer): pull WASM_64 up to a common header. 43 // TODO(titzer): pull WASM_64 up to a common header.
43 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 44 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
44 #define WASM_64 1 45 #define WASM_64 1
45 #else 46 #else
46 #define WASM_64 0 47 #define WASM_64 0
47 #endif 48 #endif
48 49
(...skipping 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 2905
2905 // Convert the return value back. 2906 // Convert the return value back.
2906 Node* i32_zero = jsgraph()->Int32Constant(0); 2907 Node* i32_zero = jsgraph()->Int32Constant(0);
2907 Node* val = sig->return_count() == 0 2908 Node* val = sig->return_count() == 0
2908 ? i32_zero 2909 ? i32_zero
2909 : FromJS(call, HeapConstant(isolate->native_context()), 2910 : FromJS(call, HeapConstant(isolate->native_context()),
2910 sig->GetReturn()); 2911 sig->GetReturn());
2911 Return(val); 2912 Return(val);
2912 } 2913 }
2913 2914
2915 void WasmGraphBuilder::BuildWasmToInterpreter(
2916 uint32_t function_index, wasm::FunctionSig* sig,
2917 Handle<WasmInstanceObject> instance) {
2918 int wasm_count = static_cast<int>(sig->parameter_count());
2919 int param_count = jsgraph()->machine()->Is64()
2920 ? wasm_count
2921 : Int64Lowering::GetParameterCountAfterLowering(sig);
2922
2923 // Build the start and the parameter nodes.
2924 Node* start = Start(param_count + 3);
2925 *effect_ = start;
2926 *control_ = start;
2927
2928 auto build_runtime_call = [&](Runtime::FunctionId f) -> Node* {
2929 Node* parameters[] = {
2930 jsgraph()->SmiConstant(function_index), // function index
2931 jsgraph()->HeapConstant(instance), // wasm instance
2932 };
2933 return BuildCallToRuntime(
2934 f, jsgraph(), jsgraph()->isolate()->native_context(), parameters,
2935 arraysize(parameters), effect_, *control_);
2936 };
2937
2938 // Get a buffer to store all parameters.
2939 Node* arg_buffer = build_runtime_call(Runtime::kGetWasmInterpreterBuffer);
titzer 2017/01/10 19:00:51 I think we can put this buffer into the stack fram
titzer 2017/01/10 19:02:47 Actually, now that I think about it, we might be a
Clemens Hammacher 2017/01/11 15:05:29 Done: http://crrev.com/2624183002 Using a special
2940
2941 // Now store all our parameters to the buffer.
2942 int param_index = 0;
2943 int offset = 0;
2944 for (int i = 0; i < wasm_count; i++) {
2945 Node* param = Param(param_index++);
2946 bool is_i64_as_two_params =
2947 jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kWasmI64;
2948 MachineRepresentation param_rep =
2949 is_i64_as_two_params ? wasm::kWasmI32 : sig->GetParam(i);
2950 StoreRepresentation store_rep(param_rep, WriteBarrierKind::kNoWriteBarrier);
2951 *effect_ =
2952 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer,
2953 Int32Constant(offset), param, *effect_, *control_);
2954 offset += 1 << ElementSizeLog2Of(param_rep);
2955 if (is_i64_as_two_params) {
titzer 2017/01/10 19:00:51 I think this might be backward for big-endian plat
Clemens Hammacher 2017/01/11 15:05:29 According to AddParameterNodes (line 2811) and Bui
2956 // Also store the upper half.
2957 param = Param(param_index++);
2958 StoreRepresentation store_rep(wasm::kWasmI32,
2959 WriteBarrierKind::kNoWriteBarrier);
2960 *effect_ =
2961 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer,
2962 Int32Constant(offset), param, *effect_, *control_);
2963 offset += 1 << ElementSizeLog2Of(wasm::kWasmI32);
titzer 2017/01/10 19:00:51 sizeof(int32_t) is also fine.
Clemens Hammacher 2017/01/11 15:05:29 Yes, but this way it is the same expression as 7 l
2964 }
2965 }
2966 DCHECK_EQ(param_count, param_index);
2967
2968 build_runtime_call(Runtime::kWasmRunInterpreter);
2969
2970 // Read back the return value.
2971 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 &&
2972 sig->GetReturn() == wasm::kWasmI64) {
2973 MachineType load_rep = wasm::WasmOpcodes::MachineTypeFor(wasm::kWasmI32);
2974 Node* lower =
2975 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer,
2976 Int32Constant(0), *effect_, *control_);
2977 Node* upper =
2978 graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer,
2979 Int32Constant(4), *effect_, *control_);
2980 Return(upper, lower);
2981 } else {
2982 Node* val;
2983 if (sig->return_count() == 0) {
2984 val = Int32Constant(0);
2985 } else {
2986 MachineType load_rep =
2987 wasm::WasmOpcodes::MachineTypeFor(sig->GetReturn());
2988 val = graph()->NewNode(jsgraph()->machine()->Load(load_rep), arg_buffer,
2989 Int32Constant(0), *effect_, *control_);
2990 }
2991 Return(val);
2992 }
2993 }
2994
2914 Node* WasmGraphBuilder::MemBuffer(uint32_t offset) { 2995 Node* WasmGraphBuilder::MemBuffer(uint32_t offset) {
2915 DCHECK(module_ && module_->instance); 2996 DCHECK(module_ && module_->instance);
2916 if (offset == 0) { 2997 if (offset == 0) {
2917 if (!mem_buffer_) { 2998 if (!mem_buffer_) {
2918 mem_buffer_ = jsgraph()->RelocatableIntPtrConstant( 2999 mem_buffer_ = jsgraph()->RelocatableIntPtrConstant(
2919 reinterpret_cast<uintptr_t>(module_->instance->mem_start), 3000 reinterpret_cast<uintptr_t>(module_->instance->mem_start),
2920 RelocInfo::WASM_MEMORY_REFERENCE); 3001 RelocInfo::WASM_MEMORY_REFERENCE);
2921 } 3002 }
2922 return mem_buffer_; 3003 return mem_buffer_;
2923 } else { 3004 } else {
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
3479 } 3560 }
3480 RecordFunctionCompilation( 3561 RecordFunctionCompilation(
3481 CodeEventListener::FUNCTION_TAG, isolate, code, "wasm-to-js", index, 3562 CodeEventListener::FUNCTION_TAG, isolate, code, "wasm-to-js", index,
3482 {module_name->ToCString().get(), module_name->length()}, 3563 {module_name->ToCString().get(), module_name->length()},
3483 {function_name, function_name_size}); 3564 {function_name, function_name_size});
3484 } 3565 }
3485 3566
3486 return code; 3567 return code;
3487 } 3568 }
3488 3569
3570 Handle<Code> CompileWasmToInterpreter(Isolate* isolate, uint32_t func_index,
3571 wasm::FunctionSig* sig,
3572 Handle<WasmInstanceObject> instance) {
3573 //----------------------------------------------------------------------------
3574 // Create the Graph
3575 //----------------------------------------------------------------------------
3576 Zone zone(isolate->allocator(), ZONE_NAME);
3577 Graph graph(&zone);
3578 CommonOperatorBuilder common(&zone);
3579 MachineOperatorBuilder machine(&zone);
3580 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
3581
3582 Node* control = nullptr;
3583 Node* effect = nullptr;
3584
3585 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig);
3586 builder.set_control_ptr(&control);
3587 builder.set_effect_ptr(&effect);
3588 builder.BuildWasmToInterpreter(func_index, sig, instance);
3589
3590 Handle<Code> code = Handle<Code>::null();
3591 {
3592 if (FLAG_trace_turbo_graph) { // Simple textual RPO.
3593 OFStream os(stdout);
3594 os << "-- Wasm to interpreter graph -- " << std::endl;
3595 os << AsRPO(graph);
3596 }
3597
3598 // Schedule and compile to machine code.
3599 CallDescriptor* incoming =
3600 wasm::ModuleEnv::GetWasmCallDescriptor(&zone, sig);
3601 if (machine.Is32()) {
3602 incoming = wasm::ModuleEnv::GetI32WasmCallDescriptor(&zone, incoming);
3603 }
3604 Code::Flags flags = Code::ComputeFlags(Code::WASM_TO_INTERPRETER);
3605 EmbeddedVector<char, 32> debug_name;
3606 int name_len = SNPrintF(debug_name, "wasm-to-interpreter#%d", func_index);
3607 DCHECK(name_len > 0 && name_len < debug_name.length());
3608 debug_name.Truncate(name_len);
3609 DCHECK_EQ('\0', debug_name.start()[debug_name.length()]);
3610
3611 CompilationInfo info(debug_name, isolate, &zone, flags);
3612 code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr);
3613 #ifdef ENABLE_DISASSEMBLER
3614 if (FLAG_print_opt_code && !code.is_null()) {
3615 OFStream os(stdout);
3616 code->Disassemble(debug_name.start(), os);
3617 }
3618 #endif
3619
3620 if (isolate->logger()->is_logging_code_events() ||
3621 isolate->is_profiling()) {
3622 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate, code,
3623 "wasm-to-interpreter", func_index,
3624 wasm::WasmName("module"), debug_name);
3625 }
3626 }
3627
3628 Handle<FixedArray> deopt_data = isolate->factory()->NewFixedArray(1, TENURED);
3629 Handle<WeakCell> weak_instance = isolate->factory()->NewWeakCell(instance);
3630 deopt_data->set(0, *weak_instance);
3631 code->set_deoptimization_data(*deopt_data);
3632
3633 return code;
3634 }
3635
3489 SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( 3636 SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
3490 double* decode_ms) { 3637 double* decode_ms) {
3491 base::ElapsedTimer decode_timer; 3638 base::ElapsedTimer decode_timer;
3492 if (FLAG_trace_wasm_decode_time) { 3639 if (FLAG_trace_wasm_decode_time) {
3493 decode_timer.Start(); 3640 decode_timer.Start();
3494 } 3641 }
3495 // Create a TF graph during decoding. 3642 // Create a TF graph during decoding.
3496 3643
3497 Graph* graph = jsgraph_->graph(); 3644 Graph* graph = jsgraph_->graph();
3498 CommonOperatorBuilder* common = jsgraph_->common(); 3645 CommonOperatorBuilder* common = jsgraph_->common();
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
3686 Smi::FromInt(instruction.instr_offset)); 3833 Smi::FromInt(instruction.instr_offset));
3687 fn_protected->set(Code::kTrapDataSize * i + Code::kTrapLandingOffset, 3834 fn_protected->set(Code::kTrapDataSize * i + Code::kTrapLandingOffset,
3688 Smi::FromInt(instruction.landing_offset)); 3835 Smi::FromInt(instruction.landing_offset));
3689 } 3836 }
3690 return fn_protected; 3837 return fn_protected;
3691 } 3838 }
3692 3839
3693 } // namespace compiler 3840 } // namespace compiler
3694 } // namespace internal 3841 } // namespace internal
3695 } // namespace v8 3842 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698