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