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

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

Issue 2371833007: [wasm] Initial signal handler (Closed)
Patch Set: Avoid signed/unsigned comparisons for windows Created 3 years, 10 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/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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 inputs[count++] = control; 96 inputs[count++] = control;
97 97
98 Node* node = 98 Node* node =
99 jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs); 99 jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs);
100 *effect_ptr = node; 100 *effect_ptr = node;
101 return node; 101 return node;
102 } 102 }
103 103
104 } // namespace 104 } // namespace
105 105
106 // TODO(eholk): Support trap handlers on other platforms.
107 #if V8_TARGET_ARCH_X64 && V8_OS_LINUX
108 const bool kTrapHandlerSupported = true;
109 #else
110 const bool kTrapHandlerSupported = false;
111 #endif
112
113 // A helper that handles building graph fragments for trapping. 106 // A helper that handles building graph fragments for trapping.
114 // To avoid generating a ton of redundant code that just calls the runtime 107 // To avoid generating a ton of redundant code that just calls the runtime
115 // to trap, we generate a per-trap-reason block of code that all trap sites 108 // to trap, we generate a per-trap-reason block of code that all trap sites
116 // in this function will branch to. 109 // in this function will branch to.
117 class WasmTrapHelper : public ZoneObject { 110 class WasmTrapHelper : public ZoneObject {
118 public: 111 public:
119 explicit WasmTrapHelper(WasmGraphBuilder* builder) 112 explicit WasmTrapHelper(WasmGraphBuilder* builder)
120 : builder_(builder), 113 : builder_(builder),
121 jsgraph_(builder->jsgraph()), 114 jsgraph_(builder->jsgraph()),
122 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {} 115 graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {}
(...skipping 2679 matching lines...) Expand 10 before | Expand all | Expand 10 after
2802 int pos = 0; 2795 int pos = 0;
2803 args[pos++] = HeapConstant(wasm_code); 2796 args[pos++] = HeapConstant(wasm_code);
2804 2797
2805 // Convert JS parameters to WASM numbers. 2798 // Convert JS parameters to WASM numbers.
2806 for (int i = 0; i < wasm_count; ++i) { 2799 for (int i = 0; i < wasm_count; ++i) {
2807 Node* param = Param(i + 1); 2800 Node* param = Param(i + 1);
2808 Node* wasm_param = FromJS(param, context, sig->GetParam(i)); 2801 Node* wasm_param = FromJS(param, context, sig->GetParam(i));
2809 args[pos++] = wasm_param; 2802 args[pos++] = wasm_param;
2810 } 2803 }
2811 2804
2805 // Set the ThreadInWasm flag before we do the actual call.
2806 if (trap_handler::UseTrapHandler()) {
2807 // TODO(eholk): Set the flag directly without a runtime call. We should be
2808 // able to store directly to a location in the isolate (later TLS) that sets
2809 // the g_thread_in_wasm_code flag.
2810 BuildCallToRuntime(Runtime::kSetThreadInWasm, jsgraph(),
2811 jsgraph()->isolate()->native_context(), nullptr, 0,
2812 effect_, *control_);
2813 }
2814
2812 args[pos++] = *effect_; 2815 args[pos++] = *effect_;
2813 args[pos++] = *control_; 2816 args[pos++] = *control_;
2814 2817
2815 // Call the WASM code. 2818 // Call the WASM code.
2816 CallDescriptor* desc = 2819 CallDescriptor* desc =
2817 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); 2820 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig);
2818 2821
2819 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); 2822 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args);
2820 *effect_ = call; 2823 *effect_ = call;
2824
2825 // Clear the ThreadInWasmFlag
2826 if (trap_handler::UseTrapHandler()) {
2827 // TODO(eholk): Set the flag directly without a runtime call. We should be
2828 // able to store directly to a location in the isolate (later TLS) that sets
2829 // the g_thread_in_wasm_code flag.
2830 BuildCallToRuntime(Runtime::kClearThreadInWasm, jsgraph(),
2831 jsgraph()->isolate()->native_context(), nullptr, 0,
2832 effect_, *control_);
2833 }
2834
2821 Node* retval = call; 2835 Node* retval = call;
2822 Node* jsval = ToJS( 2836 Node* jsval = ToJS(
2823 retval, sig->return_count() == 0 ? wasm::kWasmStmt : sig->GetReturn()); 2837 retval, sig->return_count() == 0 ? wasm::kWasmStmt : sig->GetReturn());
2824 Return(jsval); 2838 Return(jsval);
2825 } 2839 }
2826 2840
2827 int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count, 2841 int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count,
2828 wasm::FunctionSig* sig) { 2842 wasm::FunctionSig* sig) {
2829 // Convert WASM numbers to JS values. 2843 // Convert WASM numbers to JS values.
2830 int param_index = 0; 2844 int param_index = 0;
(...skipping 24 matching lines...) Expand all
2855 jsgraph()->isolate()->native_context(), nullptr, 2869 jsgraph()->isolate()->native_context(), nullptr,
2856 0, effect_, *control_)); 2870 0, effect_, *control_));
2857 return; 2871 return;
2858 } 2872 }
2859 2873
2860 Node** args = Buffer(wasm_count + 7); 2874 Node** args = Buffer(wasm_count + 7);
2861 2875
2862 Node* call; 2876 Node* call;
2863 bool direct_call = false; 2877 bool direct_call = false;
2864 2878
2879 if (trap_handler::UseTrapHandler()) {
2880 BuildCallToRuntime(Runtime::kClearThreadInWasm, jsgraph(),
2881 jsgraph()->isolate()->native_context(), nullptr, 0,
2882 effect_, *control_);
2883 }
2884
2865 if (target->IsJSFunction()) { 2885 if (target->IsJSFunction()) {
2866 Handle<JSFunction> function = Handle<JSFunction>::cast(target); 2886 Handle<JSFunction> function = Handle<JSFunction>::cast(target);
2867 if (function->shared()->internal_formal_parameter_count() == wasm_count) { 2887 if (function->shared()->internal_formal_parameter_count() == wasm_count) {
2868 direct_call = true; 2888 direct_call = true;
2869 int pos = 0; 2889 int pos = 0;
2870 args[pos++] = jsgraph()->Constant(target); // target callable. 2890 args[pos++] = jsgraph()->Constant(target); // target callable.
2871 // Receiver. 2891 // Receiver.
2872 if (is_sloppy(function->shared()->language_mode()) && 2892 if (is_sloppy(function->shared()->language_mode()) &&
2873 !function->shared()->native()) { 2893 !function->shared()->native()) {
2874 args[pos++] = 2894 args[pos++] =
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 args[pos++] = HeapConstant(isolate->native_context()); 2939 args[pos++] = HeapConstant(isolate->native_context());
2920 args[pos++] = *effect_; 2940 args[pos++] = *effect_;
2921 args[pos++] = *control_; 2941 args[pos++] = *control_;
2922 2942
2923 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); 2943 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
2924 } 2944 }
2925 2945
2926 *effect_ = call; 2946 *effect_ = call;
2927 SetSourcePosition(call, 0); 2947 SetSourcePosition(call, 0);
2928 2948
2949 if (trap_handler::UseTrapHandler()) {
2950 BuildCallToRuntime(Runtime::kSetThreadInWasm, jsgraph(),
2951 jsgraph()->isolate()->native_context(), nullptr, 0,
2952 effect_, *control_);
2953 }
2954
2929 // Convert the return value back. 2955 // Convert the return value back.
2930 Node* i32_zero = jsgraph()->Int32Constant(0); 2956 Node* i32_zero = jsgraph()->Int32Constant(0);
2931 Node* val = sig->return_count() == 0 2957 Node* val = sig->return_count() == 0
2932 ? i32_zero 2958 ? i32_zero
2933 : FromJS(call, HeapConstant(isolate->native_context()), 2959 : FromJS(call, HeapConstant(isolate->native_context()),
2934 sig->GetReturn()); 2960 sig->GetReturn());
2935 Return(val); 2961 Return(val);
2936 } 2962 }
2937 2963
2938 void WasmGraphBuilder::BuildWasmInterpreterEntry( 2964 void WasmGraphBuilder::BuildWasmInterpreterEntry(
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); 3215 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position);
3190 } 3216 }
3191 3217
3192 Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype, 3218 Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype,
3193 Node* index, uint32_t offset, 3219 Node* index, uint32_t offset,
3194 uint32_t alignment, 3220 uint32_t alignment,
3195 wasm::WasmCodePosition position) { 3221 wasm::WasmCodePosition position) {
3196 Node* load; 3222 Node* load;
3197 3223
3198 // WASM semantics throw on OOB. Introduce explicit bounds check. 3224 // WASM semantics throw on OOB. Introduce explicit bounds check.
3199 if (!FLAG_wasm_trap_handler || !kTrapHandlerSupported) { 3225 if (!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED) {
3200 BoundsCheckMem(memtype, index, offset, position); 3226 BoundsCheckMem(memtype, index, offset, position);
3201 } 3227 }
3202 bool aligned = static_cast<int>(alignment) >= 3228 bool aligned = static_cast<int>(alignment) >=
3203 ElementSizeLog2Of(memtype.representation()); 3229 ElementSizeLog2Of(memtype.representation());
3204 3230
3205 if (aligned || 3231 if (aligned ||
3206 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { 3232 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
3207 if (FLAG_wasm_trap_handler && kTrapHandlerSupported) { 3233 if (FLAG_wasm_trap_handler && V8_TRAP_HANDLER_SUPPORTED) {
3208 DCHECK(FLAG_wasm_guard_pages); 3234 DCHECK(FLAG_wasm_guard_pages);
3209 Node* position_node = jsgraph()->Int32Constant(position); 3235 Node* position_node = jsgraph()->Int32Constant(position);
3210 load = graph()->NewNode(jsgraph()->machine()->ProtectedLoad(memtype), 3236 load = graph()->NewNode(jsgraph()->machine()->ProtectedLoad(memtype),
3211 MemBuffer(offset), index, position_node, *effect_, 3237 MemBuffer(offset), index, position_node, *effect_,
3212 *control_); 3238 *control_);
3213 } else { 3239 } else {
3214 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 3240 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
3215 MemBuffer(offset), index, *effect_, *control_); 3241 MemBuffer(offset), index, *effect_, *control_);
3216 } 3242 }
3217 } else { 3243 } else {
3218 // TODO(eholk): Support unaligned loads with trap handlers. 3244 // TODO(eholk): Support unaligned loads with trap handlers.
3219 DCHECK(!FLAG_wasm_trap_handler || !kTrapHandlerSupported); 3245 DCHECK(!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED);
3220 load = graph()->NewNode(jsgraph()->machine()->UnalignedLoad(memtype), 3246 load = graph()->NewNode(jsgraph()->machine()->UnalignedLoad(memtype),
3221 MemBuffer(offset), index, *effect_, *control_); 3247 MemBuffer(offset), index, *effect_, *control_);
3222 } 3248 }
3223 3249
3224 *effect_ = load; 3250 *effect_ = load;
3225 3251
3226 #if defined(V8_TARGET_BIG_ENDIAN) 3252 #if defined(V8_TARGET_BIG_ENDIAN)
3227 load = BuildChangeEndianness(load, memtype, type); 3253 load = BuildChangeEndianness(load, memtype, type);
3228 #endif 3254 #endif
3229 3255
(...skipping 13 matching lines...) Expand all
3243 return load; 3269 return load;
3244 } 3270 }
3245 3271
3246 3272
3247 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, 3273 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
3248 uint32_t offset, uint32_t alignment, Node* val, 3274 uint32_t offset, uint32_t alignment, Node* val,
3249 wasm::WasmCodePosition position) { 3275 wasm::WasmCodePosition position) {
3250 Node* store; 3276 Node* store;
3251 3277
3252 // WASM semantics throw on OOB. Introduce explicit bounds check. 3278 // WASM semantics throw on OOB. Introduce explicit bounds check.
3253 if (!FLAG_wasm_trap_handler || !kTrapHandlerSupported) { 3279 if (!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED) {
3254 BoundsCheckMem(memtype, index, offset, position); 3280 BoundsCheckMem(memtype, index, offset, position);
3255 } 3281 }
3256 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3282 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3257 3283
3258 bool aligned = static_cast<int>(alignment) >= 3284 bool aligned = static_cast<int>(alignment) >=
3259 ElementSizeLog2Of(memtype.representation()); 3285 ElementSizeLog2Of(memtype.representation());
3260 3286
3261 #if defined(V8_TARGET_BIG_ENDIAN) 3287 #if defined(V8_TARGET_BIG_ENDIAN)
3262 val = BuildChangeEndianness(val, memtype); 3288 val = BuildChangeEndianness(val, memtype);
3263 #endif 3289 #endif
3264 3290
3265 if (aligned || 3291 if (aligned ||
3266 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { 3292 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
3267 if (FLAG_wasm_trap_handler && kTrapHandlerSupported) { 3293 if (FLAG_wasm_trap_handler && V8_TRAP_HANDLER_SUPPORTED) {
3268 Node* position_node = jsgraph()->Int32Constant(position); 3294 Node* position_node = jsgraph()->Int32Constant(position);
3269 store = graph()->NewNode( 3295 store = graph()->NewNode(
3270 jsgraph()->machine()->ProtectedStore(memtype.representation()), 3296 jsgraph()->machine()->ProtectedStore(memtype.representation()),
3271 MemBuffer(offset), index, val, position_node, *effect_, *control_); 3297 MemBuffer(offset), index, val, position_node, *effect_, *control_);
3272 } else { 3298 } else {
3273 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3299 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3274 store = 3300 store =
3275 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 3301 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
3276 index, val, *effect_, *control_); 3302 index, val, *effect_, *control_);
3277 } 3303 }
3278 } else { 3304 } else {
3279 // TODO(eholk): Support unaligned stores with trap handlers. 3305 // TODO(eholk): Support unaligned stores with trap handlers.
3280 DCHECK(!FLAG_wasm_trap_handler || !kTrapHandlerSupported); 3306 DCHECK(!FLAG_wasm_trap_handler || !V8_TRAP_HANDLER_SUPPORTED);
3281 UnalignedStoreRepresentation rep(memtype.representation()); 3307 UnalignedStoreRepresentation rep(memtype.representation());
3282 store = 3308 store =
3283 graph()->NewNode(jsgraph()->machine()->UnalignedStore(rep), 3309 graph()->NewNode(jsgraph()->machine()->UnalignedStore(rep),
3284 MemBuffer(offset), index, val, *effect_, *control_); 3310 MemBuffer(offset), index, val, *effect_, *control_);
3285 } 3311 }
3286 3312
3287 *effect_ = store; 3313 *effect_ = store;
3288 3314
3289 return store; 3315 return store;
3290 } 3316 }
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
4143 function_->code_start_offset), 4169 function_->code_start_offset),
4144 compile_ms); 4170 compile_ms);
4145 } 4171 }
4146 4172
4147 return code; 4173 return code;
4148 } 4174 }
4149 4175
4150 } // namespace compiler 4176 } // namespace compiler
4151 } // namespace internal 4177 } // namespace internal
4152 } // namespace v8 4178 } // namespace v8
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/compiler/x64/code-generator-x64.cc » ('j') | src/isolate.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698