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, bool aligned) { |
2272 Node* load; | 2271 Node* load; |
2273 | 2272 |
2274 if (module_ && module_->asm_js()) { | 2273 if (module_ && module_->asm_js()) { |
2275 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). | 2274 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). |
2276 DCHECK_EQ(0, offset); | 2275 DCHECK_EQ(0, offset); |
2277 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); | 2276 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); |
2278 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, | 2277 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, |
2279 *control_); | 2278 *control_); |
2280 } else { | 2279 } else { |
2281 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2280 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2282 BoundsCheckMem(memtype, index, offset); | 2281 BoundsCheckMem(memtype, index, offset); |
2283 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 2282 if (aligned || |
2284 MemBuffer(offset), index, *effect_, *control_); | 2283 !jsgraph()->machine()->UnalignedLoad(memtype).IsSupported()) { |
| 2284 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
| 2285 MemBuffer(offset), index, *effect_, *control_); |
| 2286 } else { |
| 2287 load = graph()->NewNode(jsgraph()->machine()->UnalignedLoad(memtype).op(), |
| 2288 MemBuffer(offset), index, *effect_, *control_); |
| 2289 } |
2285 } | 2290 } |
2286 | 2291 |
2287 *effect_ = load; | 2292 *effect_ = load; |
2288 | 2293 |
2289 if (type == wasm::kAstI64 && | 2294 if (type == wasm::kAstI64 && |
2290 ElementSizeLog2Of(memtype.representation()) < 3) { | 2295 ElementSizeLog2Of(memtype.representation()) < 3) { |
2291 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. | 2296 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. |
2292 if (memtype.IsSigned()) { | 2297 if (memtype.IsSigned()) { |
2293 // sign extend | 2298 // sign extend |
2294 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); | 2299 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); |
2295 } else { | 2300 } else { |
2296 // zero extend | 2301 // zero extend |
2297 load = | 2302 load = |
2298 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); | 2303 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); |
2299 } | 2304 } |
2300 } | 2305 } |
2301 | 2306 |
2302 return load; | 2307 return load; |
2303 } | 2308 } |
2304 | 2309 |
2305 | |
2306 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 2310 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
2307 uint32_t offset, Node* val) { | 2311 uint32_t offset, bool aligned, Node* val) { |
2308 Node* store; | 2312 Node* store; |
2309 if (module_ && module_->asm_js()) { | 2313 if (module_ && module_->asm_js()) { |
2310 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). | 2314 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). |
2311 DCHECK_EQ(0, offset); | 2315 DCHECK_EQ(0, offset); |
2312 const Operator* op = | 2316 const Operator* op = |
2313 jsgraph()->machine()->CheckedStore(memtype.representation()); | 2317 jsgraph()->machine()->CheckedStore(memtype.representation()); |
2314 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, | 2318 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, |
2315 *control_); | 2319 *control_); |
2316 } else { | 2320 } else { |
2317 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2321 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2318 BoundsCheckMem(memtype, index, offset); | 2322 BoundsCheckMem(memtype, index, offset); |
2319 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 2323 if (aligned || |
2320 store = | 2324 !jsgraph() |
2321 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), | 2325 ->machine() |
2322 index, val, *effect_, *control_); | 2326 ->UnalignedStore(memtype.representation()) |
| 2327 .IsSupported()) { |
| 2328 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| 2329 store = |
| 2330 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |
| 2331 index, val, *effect_, *control_); |
| 2332 } else { |
| 2333 store = graph()->NewNode( |
| 2334 jsgraph()->machine()->UnalignedStore(memtype.representation()).op(), |
| 2335 MemBuffer(offset), index, val, *effect_, *control_); |
| 2336 } |
2323 } | 2337 } |
2324 *effect_ = store; | 2338 *effect_ = store; |
2325 return store; | 2339 return store; |
2326 } | 2340 } |
2327 | 2341 |
2328 | 2342 |
2329 void WasmGraphBuilder::PrintDebugName(Node* node) { | 2343 void WasmGraphBuilder::PrintDebugName(Node* node) { |
2330 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); | 2344 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); |
2331 } | 2345 } |
2332 | 2346 |
(...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), | 2667 static_cast<int>(function.code_end_offset - function.code_start_offset), |
2654 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); | 2668 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); |
2655 } | 2669 } |
2656 return code; | 2670 return code; |
2657 } | 2671 } |
2658 | 2672 |
2659 | 2673 |
2660 } // namespace compiler | 2674 } // namespace compiler |
2661 } // namespace internal | 2675 } // namespace internal |
2662 } // namespace v8 | 2676 } // namespace v8 |
OLD | NEW |