| 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/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
| 10 #include "src/base/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
| (...skipping 2928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2939 : Int64Lowering::GetParameterCountAfterLowering(sig); | 2939 : Int64Lowering::GetParameterCountAfterLowering(sig); |
| 2940 | 2940 |
| 2941 // Build the start and the parameter nodes. | 2941 // Build the start and the parameter nodes. |
| 2942 Node* start = Start(param_count + 3); | 2942 Node* start = Start(param_count + 3); |
| 2943 *effect_ = start; | 2943 *effect_ = start; |
| 2944 *control_ = start; | 2944 *control_ = start; |
| 2945 | 2945 |
| 2946 // Compute size for the argument buffer. | 2946 // Compute size for the argument buffer. |
| 2947 int args_size_bytes = 0; | 2947 int args_size_bytes = 0; |
| 2948 for (int i = 0; i < wasm_count; i++) { | 2948 for (int i = 0; i < wasm_count; i++) { |
| 2949 args_size_bytes += 1 << ElementSizeLog2Of(sig->GetParam(i)); | 2949 args_size_bytes += |
| 2950 RoundUpToMultipleOfPowOf2(1 << ElementSizeLog2Of(sig->GetParam(i)), 8); |
| 2950 } | 2951 } |
| 2951 | 2952 |
| 2952 // The return value is also passed via this buffer: | 2953 // The return value is also passed via this buffer: |
| 2953 DCHECK_GE(wasm::kV8MaxWasmFunctionReturns, sig->return_count()); | 2954 DCHECK_GE(wasm::kV8MaxWasmFunctionReturns, sig->return_count()); |
| 2954 // TODO(wasm): Handle multi-value returns. | 2955 // TODO(wasm): Handle multi-value returns. |
| 2955 DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns); | 2956 DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns); |
| 2956 int return_size_bytes = | 2957 int return_size_bytes = |
| 2957 sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0)); | 2958 sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0)); |
| 2958 | 2959 |
| 2959 // Get a stack slot for the arguments. | 2960 // Get a stack slot for the arguments. |
| 2960 Node* arg_buffer = args_size_bytes == 0 && return_size_bytes == 0 | 2961 Node* arg_buffer = args_size_bytes == 0 && return_size_bytes == 0 |
| 2961 ? jsgraph()->IntPtrConstant(0) | 2962 ? jsgraph()->IntPtrConstant(0) |
| 2962 : graph()->NewNode(jsgraph()->machine()->StackSlot( | 2963 : graph()->NewNode(jsgraph()->machine()->StackSlot( |
| 2963 std::max(args_size_bytes, return_size_bytes))); | 2964 std::max(args_size_bytes, return_size_bytes))); |
| 2964 | 2965 |
| 2965 // Now store all our arguments to the buffer. | 2966 // Now store all our arguments to the buffer. |
| 2966 int param_index = 0; | 2967 int param_index = 0; |
| 2967 int offset = 0; | 2968 int offset = 0; |
| 2968 for (int i = 0; i < wasm_count; i++) { | 2969 for (int i = 0; i < wasm_count; i++) { |
| 2969 Node* param = Param(param_index++); | 2970 Node* param = Param(param_index++); |
| 2970 bool is_i64_as_two_params = | 2971 bool is_i64_as_two_params = |
| 2971 jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kWasmI64; | 2972 jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kWasmI64; |
| 2972 MachineRepresentation param_rep = | 2973 |
| 2973 is_i64_as_two_params ? wasm::kWasmI32 : sig->GetParam(i); | |
| 2974 StoreRepresentation store_rep(param_rep, WriteBarrierKind::kNoWriteBarrier); | |
| 2975 *effect_ = | |
| 2976 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, | |
| 2977 Int32Constant(offset), param, *effect_, *control_); | |
| 2978 offset += 1 << ElementSizeLog2Of(param_rep); | |
| 2979 // TODO(clemensh): Respect endianess here. Might need to swap upper and | |
| 2980 // lower word. | |
| 2981 if (is_i64_as_two_params) { | 2974 if (is_i64_as_two_params) { |
| 2982 // Also store the upper half. | |
| 2983 param = Param(param_index++); | |
| 2984 StoreRepresentation store_rep(wasm::kWasmI32, | 2975 StoreRepresentation store_rep(wasm::kWasmI32, |
| 2985 WriteBarrierKind::kNoWriteBarrier); | 2976 WriteBarrierKind::kNoWriteBarrier); |
| 2986 *effect_ = | 2977 *effect_ = |
| 2987 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, | 2978 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, |
| 2979 Int32Constant(offset + kInt64LowerHalfMemoryOffset), |
| 2980 param, *effect_, *control_); |
| 2981 |
| 2982 param = Param(param_index++); |
| 2983 *effect_ = |
| 2984 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, |
| 2985 Int32Constant(offset + kInt64UpperHalfMemoryOffset), |
| 2986 param, *effect_, *control_); |
| 2987 offset += 8; |
| 2988 |
| 2989 } else { |
| 2990 MachineRepresentation param_rep = sig->GetParam(i); |
| 2991 StoreRepresentation store_rep(param_rep, |
| 2992 WriteBarrierKind::kNoWriteBarrier); |
| 2993 *effect_ = |
| 2994 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, |
| 2988 Int32Constant(offset), param, *effect_, *control_); | 2995 Int32Constant(offset), param, *effect_, *control_); |
| 2989 offset += 1 << ElementSizeLog2Of(wasm::kWasmI32); | 2996 offset += RoundUpToMultipleOfPowOf2(1 << ElementSizeLog2Of(param_rep), 8); |
| 2990 } | 2997 } |
| 2998 |
| 2999 DCHECK(IsAligned(offset, 8)); |
| 2991 } | 3000 } |
| 2992 DCHECK_EQ(param_count, param_index); | 3001 DCHECK_EQ(param_count, param_index); |
| 2993 DCHECK_EQ(args_size_bytes, offset); | 3002 DCHECK_EQ(args_size_bytes, offset); |
| 2994 | 3003 |
| 2995 // We are passing the raw arg_buffer here. To the GC and other parts, it looks | 3004 // We are passing the raw arg_buffer here. To the GC and other parts, it looks |
| 2996 // like a Smi (lowest bit not set). In the runtime function however, don't | 3005 // like a Smi (lowest bit not set). In the runtime function however, don't |
| 2997 // call Smi::value on it, but just cast it to a byte pointer. | 3006 // call Smi::value on it, but just cast it to a byte pointer. |
| 2998 Node* parameters[] = { | 3007 Node* parameters[] = { |
| 2999 jsgraph()->HeapConstant(instance), // wasm instance | 3008 jsgraph()->HeapConstant(instance), // wasm instance |
| 3000 jsgraph()->SmiConstant(function_index), // function index | 3009 jsgraph()->SmiConstant(function_index), // function index |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3881 | 3890 |
| 3882 Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, | 3891 Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, |
| 3883 wasm::FunctionSig* sig, | 3892 wasm::FunctionSig* sig, |
| 3884 Handle<WasmInstanceObject> instance) { | 3893 Handle<WasmInstanceObject> instance) { |
| 3885 //---------------------------------------------------------------------------- | 3894 //---------------------------------------------------------------------------- |
| 3886 // Create the Graph | 3895 // Create the Graph |
| 3887 //---------------------------------------------------------------------------- | 3896 //---------------------------------------------------------------------------- |
| 3888 Zone zone(isolate->allocator(), ZONE_NAME); | 3897 Zone zone(isolate->allocator(), ZONE_NAME); |
| 3889 Graph graph(&zone); | 3898 Graph graph(&zone); |
| 3890 CommonOperatorBuilder common(&zone); | 3899 CommonOperatorBuilder common(&zone); |
| 3891 MachineOperatorBuilder machine(&zone); | 3900 MachineOperatorBuilder machine( |
| 3901 &zone, MachineType::PointerRepresentation(), |
| 3902 InstructionSelector::SupportedMachineOperatorFlags(), |
| 3903 InstructionSelector::AlignmentRequirements()); |
| 3892 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3904 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
| 3893 | 3905 |
| 3894 Node* control = nullptr; | 3906 Node* control = nullptr; |
| 3895 Node* effect = nullptr; | 3907 Node* effect = nullptr; |
| 3896 | 3908 |
| 3897 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); | 3909 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); |
| 3898 builder.set_control_ptr(&control); | 3910 builder.set_control_ptr(&control); |
| 3899 builder.set_effect_ptr(&effect); | 3911 builder.set_effect_ptr(&effect); |
| 3900 builder.BuildWasmInterpreterEntry(func_index, sig, instance); | 3912 builder.BuildWasmInterpreterEntry(func_index, sig, instance); |
| 3901 | 3913 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4135 function_->code_end_offset - function_->code_start_offset, | 4147 function_->code_end_offset - function_->code_start_offset, |
| 4136 codegen_ms); | 4148 codegen_ms); |
| 4137 } | 4149 } |
| 4138 | 4150 |
| 4139 return code; | 4151 return code; |
| 4140 } | 4152 } |
| 4141 | 4153 |
| 4142 } // namespace compiler | 4154 } // namespace compiler |
| 4143 } // namespace internal | 4155 } // namespace internal |
| 4144 } // namespace v8 | 4156 } // namespace v8 |
| OLD | NEW |