@@ -2767,33 +2767,73 @@ class LiftoffCompiler {
2767
2767
return index ;
2768
2768
}
2769
2769
2770
+ bool IndexStaticallyInBounds (const LiftoffAssembler::VarState& index_slot,
2771
+ int access_size, uintptr_t * offset) {
2772
+ if (!index_slot.is_const ()) return false ;
2773
+
2774
+ // Potentially zero extend index (which is a 32-bit constant).
2775
+ const uintptr_t index = static_cast <uint32_t >(index_slot.i32_const ());
2776
+ const uintptr_t effective_offset = index + *offset;
2777
+
2778
+ if (effective_offset < index // overflow
2779
+ || !base::IsInBounds<uintptr_t >(effective_offset, access_size,
2780
+ env_->min_memory_size )) {
2781
+ return false ;
2782
+ }
2783
+
2784
+ *offset = effective_offset;
2785
+ return true ;
2786
+ }
2787
+
2770
2788
void LoadMem (FullDecoder* decoder, LoadType type,
2771
2789
const MemoryAccessImmediate<validate>& imm,
2772
2790
const Value& index_val, Value* result) {
2773
2791
ValueKind kind = type.value_type ().kind ();
2792
+ RegClass rc = reg_class_for (kind);
2774
2793
if (!CheckSupportedType (decoder, kind, " load" )) return ;
2775
- LiftoffRegister full_index = __ PopToRegister ();
2776
- Register index = BoundsCheckMem (decoder, type.size (), imm.offset ,
2777
- full_index, {}, kDontForceCheck );
2778
- if (index == no_reg) return ;
2779
2794
2780
2795
uintptr_t offset = imm.offset ;
2781
- LiftoffRegList pinned = LiftoffRegList::ForRegs (index );
2782
- index = AddMemoryMasking (index , &offset, &pinned);
2783
- DEBUG_CODE_COMMENT (" load from memory" );
2784
- Register addr = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2785
- LOAD_INSTANCE_FIELD (addr, MemoryStart, kSystemPointerSize , pinned);
2786
- RegClass rc = reg_class_for (kind);
2787
- LiftoffRegister value = pinned.set (__ GetUnusedRegister (rc, pinned));
2788
- uint32_t protected_load_pc = 0 ;
2789
- __ Load (value, addr, index , offset, type, pinned, &protected_load_pc, true );
2790
- if (env_->use_trap_handler ) {
2791
- AddOutOfLineTrap (decoder, WasmCode::kThrowWasmTrapMemOutOfBounds ,
2792
- protected_load_pc);
2796
+ Register index = no_reg;
2797
+
2798
+ // Only look at the slot, do not pop it yet (will happen in PopToRegister
2799
+ // below, if this is not a statically-in-bounds index).
2800
+ auto & index_slot = __ cache_state ()->stack_state .back ();
2801
+ if (IndexStaticallyInBounds (index_slot, type.size (), &offset)) {
2802
+ __ cache_state ()->stack_state .pop_back ();
2803
+ DEBUG_CODE_COMMENT (" load from memory (constant offset)" );
2804
+ LiftoffRegList pinned;
2805
+ Register mem = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2806
+ LOAD_INSTANCE_FIELD (mem, MemoryStart, kSystemPointerSize , pinned);
2807
+ LiftoffRegister value = pinned.set (__ GetUnusedRegister (rc, pinned));
2808
+ __ Load (value, mem, no_reg, offset, type, pinned, nullptr , true );
2809
+ __ PushRegister (kind, value);
2810
+ } else {
2811
+ LiftoffRegister full_index = __ PopToRegister ();
2812
+ index = BoundsCheckMem (decoder, type.size (), offset, full_index, {},
2813
+ kDontForceCheck );
2814
+ if (index == no_reg) return ;
2815
+
2816
+ DEBUG_CODE_COMMENT (" load from memory" );
2817
+ LiftoffRegList pinned = LiftoffRegList::ForRegs (index );
2818
+ index = AddMemoryMasking (index , &offset, &pinned);
2819
+
2820
+ // Load the memory start address only now to reduce register pressure
2821
+ // (important on ia32).
2822
+ Register mem = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2823
+ LOAD_INSTANCE_FIELD (mem, MemoryStart, kSystemPointerSize , pinned);
2824
+ LiftoffRegister value = pinned.set (__ GetUnusedRegister (rc, pinned));
2825
+
2826
+ uint32_t protected_load_pc = 0 ;
2827
+ __ Load (value, mem, index , offset, type, pinned, &protected_load_pc,
2828
+ true );
2829
+ if (env_->use_trap_handler ) {
2830
+ AddOutOfLineTrap (decoder, WasmCode::kThrowWasmTrapMemOutOfBounds ,
2831
+ protected_load_pc);
2832
+ }
2833
+ __ PushRegister (kind, value);
2793
2834
}
2794
- __ PushRegister (kind, value);
2795
2835
2796
- if (FLAG_trace_wasm_memory) {
2836
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
2797
2837
TraceMemoryOperation (false , type.mem_type ().representation (), index ,
2798
2838
offset, decoder->position ());
2799
2839
}
@@ -2836,7 +2876,7 @@ class LiftoffCompiler {
2836
2876
}
2837
2877
__ PushRegister (kS128 , value);
2838
2878
2839
- if (FLAG_trace_wasm_memory) {
2879
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
2840
2880
// Again load extend is different.
2841
2881
MachineRepresentation mem_rep =
2842
2882
transform == LoadTransformationKind::kExtend
@@ -2878,7 +2918,7 @@ class LiftoffCompiler {
2878
2918
2879
2919
__ PushRegister (kS128 , result);
2880
2920
2881
- if (FLAG_trace_wasm_memory) {
2921
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
2882
2922
TraceMemoryOperation (false , type.mem_type ().representation (), index ,
2883
2923
offset, decoder->position ());
2884
2924
}
@@ -2889,29 +2929,45 @@ class LiftoffCompiler {
2889
2929
const Value& index_val, const Value& value_val) {
2890
2930
ValueKind kind = type.value_type ().kind ();
2891
2931
if (!CheckSupportedType (decoder, kind, " store" )) return ;
2932
+
2892
2933
LiftoffRegList pinned;
2893
2934
LiftoffRegister value = pinned.set (__ PopToRegister ());
2894
- LiftoffRegister full_index = __ PopToRegister (pinned);
2895
- Register index = BoundsCheckMem (decoder, type.size (), imm.offset ,
2896
- full_index, pinned, kDontForceCheck );
2897
- if (index == no_reg) return ;
2898
2935
2899
2936
uintptr_t offset = imm.offset ;
2900
- pinned.set (index );
2901
- index = AddMemoryMasking (index , &offset, &pinned);
2902
- DEBUG_CODE_COMMENT (" store to memory" );
2903
- Register addr = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2904
- LOAD_INSTANCE_FIELD (addr, MemoryStart, kSystemPointerSize , pinned);
2905
- uint32_t protected_store_pc = 0 ;
2906
- LiftoffRegList outer_pinned;
2907
- if (FLAG_trace_wasm_memory) outer_pinned.set (index );
2908
- __ Store (addr, index , offset, value, type, outer_pinned,
2909
- &protected_store_pc, true );
2910
- if (env_->use_trap_handler ) {
2911
- AddOutOfLineTrap (decoder, WasmCode::kThrowWasmTrapMemOutOfBounds ,
2912
- protected_store_pc);
2937
+ Register index = no_reg;
2938
+
2939
+ auto & index_slot = __ cache_state ()->stack_state .back ();
2940
+ if (IndexStaticallyInBounds (index_slot, type.size (), &offset)) {
2941
+ __ cache_state ()->stack_state .pop_back ();
2942
+ DEBUG_CODE_COMMENT (" store to memory (constant offset)" );
2943
+ Register mem = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2944
+ LOAD_INSTANCE_FIELD (mem, MemoryStart, kSystemPointerSize , pinned);
2945
+ __ Store (mem, no_reg, offset, value, type, pinned, nullptr , true );
2946
+ } else {
2947
+ LiftoffRegister full_index = __ PopToRegister (pinned);
2948
+ index = BoundsCheckMem (decoder, type.size (), imm.offset , full_index,
2949
+ pinned, kDontForceCheck );
2950
+ if (index == no_reg) return ;
2951
+
2952
+ pinned.set (index );
2953
+ index = AddMemoryMasking (index , &offset, &pinned);
2954
+ DEBUG_CODE_COMMENT (" store to memory" );
2955
+ uint32_t protected_store_pc = 0 ;
2956
+ // Load the memory start address only now to reduce register pressure
2957
+ // (important on ia32).
2958
+ Register mem = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
2959
+ LOAD_INSTANCE_FIELD (mem, MemoryStart, kSystemPointerSize , pinned);
2960
+ LiftoffRegList outer_pinned;
2961
+ if (V8_UNLIKELY (FLAG_trace_wasm_memory)) outer_pinned.set (index );
2962
+ __ Store (mem, index , offset, value, type, outer_pinned,
2963
+ &protected_store_pc, true );
2964
+ if (env_->use_trap_handler ) {
2965
+ AddOutOfLineTrap (decoder, WasmCode::kThrowWasmTrapMemOutOfBounds ,
2966
+ protected_store_pc);
2967
+ }
2913
2968
}
2914
- if (FLAG_trace_wasm_memory) {
2969
+
2970
+ if (V8_UNLIKELY (FLAG_trace_wasm_memory)) {
2915
2971
TraceMemoryOperation (true , type.mem_rep (), index , offset,
2916
2972
decoder->position ());
2917
2973
}
@@ -2940,7 +2996,7 @@ class LiftoffCompiler {
2940
2996
AddOutOfLineTrap (decoder, WasmCode::kThrowWasmTrapMemOutOfBounds ,
2941
2997
protected_store_pc);
2942
2998
}
2943
- if (FLAG_trace_wasm_memory) {
2999
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
2944
3000
TraceMemoryOperation (true , type.mem_rep (), index , offset,
2945
3001
decoder->position ());
2946
3002
}
@@ -4156,9 +4212,9 @@ class LiftoffCompiler {
4156
4212
Register addr = pinned.set (__ GetUnusedRegister (kGpReg , pinned)).gp ();
4157
4213
LOAD_INSTANCE_FIELD (addr, MemoryStart, kSystemPointerSize , pinned);
4158
4214
LiftoffRegList outer_pinned;
4159
- if (FLAG_trace_wasm_memory) outer_pinned.set (index );
4215
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) outer_pinned.set (index );
4160
4216
__ AtomicStore (addr, index , offset, value, type, outer_pinned);
4161
- if (FLAG_trace_wasm_memory) {
4217
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
4162
4218
TraceMemoryOperation (true , type.mem_rep (), index , offset,
4163
4219
decoder->position ());
4164
4220
}
@@ -4184,7 +4240,7 @@ class LiftoffCompiler {
4184
4240
__ AtomicLoad (value, addr, index , offset, type, pinned);
4185
4241
__ PushRegister (kind, value);
4186
4242
4187
- if (FLAG_trace_wasm_memory) {
4243
+ if (V8_UNLIKELY ( FLAG_trace_wasm_memory) ) {
4188
4244
TraceMemoryOperation (false , type.mem_type ().representation (), index ,
4189
4245
offset, decoder->position ());
4190
4246
}
0 commit comments