| 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 |