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 "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
8 | 8 |
9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2259 size_t limit = size - offset - memsize; | 2259 size_t limit = size - offset - memsize; |
2260 CHECK(limit <= kMaxUInt32); | 2260 CHECK(limit <= kMaxUInt32); |
2261 cond = graph()->NewNode( | 2261 cond = graph()->NewNode( |
2262 jsgraph()->machine()->Uint32LessThanOrEqual(), index, | 2262 jsgraph()->machine()->Uint32LessThanOrEqual(), index, |
2263 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); | 2263 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); |
2264 } | 2264 } |
2265 | 2265 |
2266 trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); | 2266 trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); |
2267 } | 2267 } |
2268 | 2268 |
2269 | |
2270 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, | 2269 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
2271 Node* index, uint32_t offset) { | 2270 Node* index, uint32_t offset, |
| 2271 uint32_t alignment) { |
2272 Node* load; | 2272 Node* load; |
2273 | 2273 |
2274 if (module_ && module_->asm_js()) { | 2274 if (module_ && module_->asm_js()) { |
2275 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). | 2275 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). |
2276 DCHECK_EQ(0, offset); | 2276 DCHECK_EQ(0, offset); |
2277 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); | 2277 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); |
2278 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, | 2278 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, |
2279 *control_); | 2279 *control_); |
2280 } else { | 2280 } else { |
2281 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2281 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2282 BoundsCheckMem(memtype, index, offset); | 2282 BoundsCheckMem(memtype, index, offset); |
2283 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 2283 bool aligned = alignment >= ElementSizeLog2Of(memtype.representation()); |
2284 MemBuffer(offset), index, *effect_, *control_); | 2284 if (aligned || |
| 2285 !jsgraph()->machine()->UnalignedLoad(memtype).IsSupported()) { |
| 2286 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
| 2287 MemBuffer(offset), index, *effect_, *control_); |
| 2288 } else { |
| 2289 load = graph()->NewNode(jsgraph()->machine()->UnalignedLoad(memtype).op(), |
| 2290 MemBuffer(offset), index, *effect_, *control_); |
| 2291 } |
2285 } | 2292 } |
2286 | 2293 |
2287 *effect_ = load; | 2294 *effect_ = load; |
2288 | 2295 |
2289 if (type == wasm::kAstI64 && | 2296 if (type == wasm::kAstI64 && |
2290 ElementSizeLog2Of(memtype.representation()) < 3) { | 2297 ElementSizeLog2Of(memtype.representation()) < 3) { |
2291 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. | 2298 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. |
2292 if (memtype.IsSigned()) { | 2299 if (memtype.IsSigned()) { |
2293 // sign extend | 2300 // sign extend |
2294 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); | 2301 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); |
2295 } else { | 2302 } else { |
2296 // zero extend | 2303 // zero extend |
2297 load = | 2304 load = |
2298 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); | 2305 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); |
2299 } | 2306 } |
2300 } | 2307 } |
2301 | 2308 |
2302 return load; | 2309 return load; |
2303 } | 2310 } |
2304 | 2311 |
2305 | |
2306 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 2312 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
2307 uint32_t offset, Node* val) { | 2313 uint32_t offset, uint32_t alignment, |
| 2314 Node* val) { |
2308 Node* store; | 2315 Node* store; |
2309 if (module_ && module_->asm_js()) { | 2316 if (module_ && module_->asm_js()) { |
2310 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). | 2317 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). |
2311 DCHECK_EQ(0, offset); | 2318 DCHECK_EQ(0, offset); |
2312 const Operator* op = | 2319 const Operator* op = |
2313 jsgraph()->machine()->CheckedStore(memtype.representation()); | 2320 jsgraph()->machine()->CheckedStore(memtype.representation()); |
2314 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, | 2321 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, |
2315 *control_); | 2322 *control_); |
2316 } else { | 2323 } else { |
2317 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2324 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2318 BoundsCheckMem(memtype, index, offset); | 2325 BoundsCheckMem(memtype, index, offset); |
2319 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 2326 bool aligned = alignment >= ElementSizeLog2Of(memtype.representation()); |
2320 store = | 2327 if (aligned || |
2321 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), | 2328 !jsgraph() |
2322 index, val, *effect_, *control_); | 2329 ->machine() |
| 2330 ->UnalignedStore(memtype.representation()) |
| 2331 .IsSupported()) { |
| 2332 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| 2333 store = |
| 2334 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |
| 2335 index, val, *effect_, *control_); |
| 2336 } else { |
| 2337 store = graph()->NewNode( |
| 2338 jsgraph()->machine()->UnalignedStore(memtype.representation()).op(), |
| 2339 MemBuffer(offset), index, val, *effect_, *control_); |
| 2340 } |
2323 } | 2341 } |
2324 *effect_ = store; | 2342 *effect_ = store; |
2325 return store; | 2343 return store; |
2326 } | 2344 } |
2327 | 2345 |
2328 | 2346 |
2329 void WasmGraphBuilder::PrintDebugName(Node* node) { | 2347 void WasmGraphBuilder::PrintDebugName(Node* node) { |
2330 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); | 2348 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); |
2331 } | 2349 } |
2332 | 2350 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 static_cast<int>(function.code_end_offset - function.code_start_offset), | 2671 static_cast<int>(function.code_end_offset - function.code_start_offset), |
2654 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); | 2672 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); |
2655 } | 2673 } |
2656 return code; | 2674 return code; |
2657 } | 2675 } |
2658 | 2676 |
2659 | 2677 |
2660 } // namespace compiler | 2678 } // namespace compiler |
2661 } // namespace internal | 2679 } // namespace internal |
2662 } // namespace v8 | 2680 } // namespace v8 |
OLD | NEW |