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 2793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 } | 2804 } |
2805 | 2805 |
2806 // The return value is also passed via this buffer: | 2806 // The return value is also passed via this buffer: |
2807 DCHECK_GE(wasm::kV8MaxWasmFunctionReturns, sig->return_count()); | 2807 DCHECK_GE(wasm::kV8MaxWasmFunctionReturns, sig->return_count()); |
2808 // TODO(wasm): Handle multi-value returns. | 2808 // TODO(wasm): Handle multi-value returns. |
2809 DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns); | 2809 DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns); |
2810 int return_size_bytes = | 2810 int return_size_bytes = |
2811 sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0)); | 2811 sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0)); |
2812 | 2812 |
2813 // Get a stack slot for the arguments. | 2813 // Get a stack slot for the arguments. |
2814 Node* arg_buffer = args_size_bytes == 0 && return_size_bytes == 0 | 2814 Node* arg_buffer = |
2815 ? jsgraph()->IntPtrConstant(0) | 2815 args_size_bytes == 0 && return_size_bytes == 0 |
2816 : graph()->NewNode(jsgraph()->machine()->StackSlot( | 2816 ? jsgraph()->IntPtrConstant(0) |
2817 std::max(args_size_bytes, return_size_bytes))); | 2817 : graph()->NewNode(jsgraph()->machine()->StackSlot( |
| 2818 std::max(args_size_bytes, return_size_bytes), 8)); |
2818 | 2819 |
2819 // Now store all our arguments to the buffer. | 2820 // Now store all our arguments to the buffer. |
2820 int param_index = 0; | 2821 int param_index = 0; |
2821 int offset = 0; | 2822 int offset = 0; |
2822 | 2823 |
2823 for (int i = 0; i < wasm_count; i++) { | 2824 for (int i = 0; i < wasm_count; i++) { |
2824 Node* param = Param(param_index++); | 2825 Node* param = Param(param_index++); |
2825 if (Int64Lowering::IsI64AsTwoParameters(jsgraph()->machine(), | 2826 if (Int64Lowering::IsI64AsTwoParameters(jsgraph()->machine(), |
2826 sig->GetParam(i))) { | 2827 sig->GetParam(i))) { |
2827 StoreRepresentation store_rep(wasm::kWasmI32, | 2828 int lower_half_offset = offset + kInt64LowerHalfMemoryOffset; |
2828 WriteBarrierKind::kNoWriteBarrier); | 2829 int upper_half_offset = offset + kInt64UpperHalfMemoryOffset; |
2829 *effect_ = | 2830 |
2830 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, | 2831 *effect_ = graph()->NewNode( |
2831 Int32Constant(offset + kInt64LowerHalfMemoryOffset), | 2832 GetSafeStoreOperator(lower_half_offset, wasm::kWasmI32), arg_buffer, |
2832 param, *effect_, *control_); | 2833 Int32Constant(lower_half_offset), param, *effect_, *control_); |
2833 | 2834 |
2834 param = Param(param_index++); | 2835 param = Param(param_index++); |
2835 *effect_ = | 2836 *effect_ = graph()->NewNode( |
2836 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, | 2837 GetSafeStoreOperator(upper_half_offset, wasm::kWasmI32), arg_buffer, |
2837 Int32Constant(offset + kInt64UpperHalfMemoryOffset), | 2838 Int32Constant(upper_half_offset), param, *effect_, *control_); |
2838 param, *effect_, *control_); | |
2839 offset += 8; | 2839 offset += 8; |
2840 | 2840 |
2841 } else { | 2841 } else { |
2842 MachineRepresentation param_rep = sig->GetParam(i); | 2842 MachineRepresentation param_rep = sig->GetParam(i); |
2843 StoreRepresentation store_rep(param_rep, | |
2844 WriteBarrierKind::kNoWriteBarrier); | |
2845 *effect_ = | 2843 *effect_ = |
2846 graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, | 2844 graph()->NewNode(GetSafeStoreOperator(offset, param_rep), arg_buffer, |
2847 Int32Constant(offset), param, *effect_, *control_); | 2845 Int32Constant(offset), param, *effect_, *control_); |
2848 offset += 1 << ElementSizeLog2Of(param_rep); | 2846 offset += 1 << ElementSizeLog2Of(param_rep); |
2849 } | 2847 } |
2850 } | 2848 } |
2851 DCHECK_EQ(param_count, param_index); | 2849 DCHECK_EQ(param_count, param_index); |
2852 DCHECK_EQ(args_size_bytes, offset); | 2850 DCHECK_EQ(args_size_bytes, offset); |
2853 | 2851 |
2854 // We are passing the raw arg_buffer here. To the GC and other parts, it looks | 2852 // We are passing the raw arg_buffer here. To the GC and other parts, it looks |
2855 // like a Smi (lowest bit not set). In the runtime function however, don't | 2853 // like a Smi (lowest bit not set). In the runtime function however, don't |
2856 // call Smi::value on it, but just cast it to a byte pointer. | 2854 // call Smi::value on it, but just cast it to a byte pointer. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3024 } | 3022 } |
3025 } | 3023 } |
3026 | 3024 |
3027 Node* cond = graph()->NewNode(jsgraph()->machine()->Uint32LessThan(), index, | 3025 Node* cond = graph()->NewNode(jsgraph()->machine()->Uint32LessThan(), index, |
3028 jsgraph()->RelocatableInt32Constant( | 3026 jsgraph()->RelocatableInt32Constant( |
3029 static_cast<uint32_t>(effective_size), | 3027 static_cast<uint32_t>(effective_size), |
3030 RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); | 3028 RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); |
3031 TrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); | 3029 TrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); |
3032 } | 3030 } |
3033 | 3031 |
| 3032 const Operator* WasmGraphBuilder::GetSafeStoreOperator(int offset, |
| 3033 wasm::ValueType type) { |
| 3034 int alignment = offset % (1 << ElementSizeLog2Of(type)); |
| 3035 if (alignment == 0 || jsgraph()->machine()->UnalignedStoreSupported( |
| 3036 MachineType::TypeForRepresentation(type), 0)) { |
| 3037 StoreRepresentation rep(type, WriteBarrierKind::kNoWriteBarrier); |
| 3038 return jsgraph()->machine()->Store(rep); |
| 3039 } |
| 3040 UnalignedStoreRepresentation rep(type); |
| 3041 return jsgraph()->machine()->UnalignedStore(rep); |
| 3042 } |
| 3043 |
3034 Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype, | 3044 Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype, |
3035 Node* index, uint32_t offset, | 3045 Node* index, uint32_t offset, |
3036 uint32_t alignment, | 3046 uint32_t alignment, |
3037 wasm::WasmCodePosition position) { | 3047 wasm::WasmCodePosition position) { |
3038 Node* load; | 3048 Node* load; |
3039 | 3049 |
3040 // WASM semantics throw on OOB. Introduce explicit bounds check. | 3050 // WASM semantics throw on OOB. Introduce explicit bounds check. |
3041 if (!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED) { | 3051 if (!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED) { |
3042 BoundsCheckMem(memtype, index, offset, position); | 3052 BoundsCheckMem(memtype, index, offset, position); |
3043 } | 3053 } |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3834 | 3844 |
3835 Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, | 3845 Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, |
3836 wasm::FunctionSig* sig, | 3846 wasm::FunctionSig* sig, |
3837 Handle<WasmInstanceObject> instance) { | 3847 Handle<WasmInstanceObject> instance) { |
3838 //---------------------------------------------------------------------------- | 3848 //---------------------------------------------------------------------------- |
3839 // Create the Graph | 3849 // Create the Graph |
3840 //---------------------------------------------------------------------------- | 3850 //---------------------------------------------------------------------------- |
3841 Zone zone(isolate->allocator(), ZONE_NAME); | 3851 Zone zone(isolate->allocator(), ZONE_NAME); |
3842 Graph graph(&zone); | 3852 Graph graph(&zone); |
3843 CommonOperatorBuilder common(&zone); | 3853 CommonOperatorBuilder common(&zone); |
3844 MachineOperatorBuilder machine(&zone); | 3854 MachineOperatorBuilder machine( |
| 3855 &zone, MachineType::PointerRepresentation(), |
| 3856 InstructionSelector::SupportedMachineOperatorFlags(), |
| 3857 InstructionSelector::AlignmentRequirements()); |
3845 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 3858 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
3846 | 3859 |
3847 Node* control = nullptr; | 3860 Node* control = nullptr; |
3848 Node* effect = nullptr; | 3861 Node* effect = nullptr; |
3849 | 3862 |
3850 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); | 3863 WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); |
3851 builder.set_control_ptr(&control); | 3864 builder.set_control_ptr(&control); |
3852 builder.set_effect_ptr(&effect); | 3865 builder.set_effect_ptr(&effect); |
3853 builder.BuildWasmInterpreterEntry(func_index, sig, instance); | 3866 builder.BuildWasmInterpreterEntry(func_index, sig, instance); |
3854 | 3867 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4128 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { | 4141 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { |
4129 WasmCompilationUnit unit(isolate, module_env, function); | 4142 WasmCompilationUnit unit(isolate, module_env, function); |
4130 unit.InitializeHandles(); | 4143 unit.InitializeHandles(); |
4131 unit.ExecuteCompilation(); | 4144 unit.ExecuteCompilation(); |
4132 return unit.FinishCompilation(thrower); | 4145 return unit.FinishCompilation(thrower); |
4133 } | 4146 } |
4134 | 4147 |
4135 } // namespace compiler | 4148 } // namespace compiler |
4136 } // namespace internal | 4149 } // namespace internal |
4137 } // namespace v8 | 4150 } // namespace v8 |
OLD | NEW |