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

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

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

Powered by Google App Engine
This is Rietveld 408576698