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/platform.h" | 9 #include "src/base/platform/platform.h" |
10 | 10 |
(...skipping 2102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2113 size_t limit = size - offset - memsize; | 2113 size_t limit = size - offset - memsize; |
2114 CHECK(limit <= kMaxUInt32); | 2114 CHECK(limit <= kMaxUInt32); |
2115 cond = graph()->NewNode( | 2115 cond = graph()->NewNode( |
2116 jsgraph()->machine()->Uint32LessThanOrEqual(), index, | 2116 jsgraph()->machine()->Uint32LessThanOrEqual(), index, |
2117 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); | 2117 jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); |
2118 } | 2118 } |
2119 | 2119 |
2120 trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); | 2120 trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); |
2121 } | 2121 } |
2122 | 2122 |
2123 | |
2124 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, | 2123 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
2125 Node* index, uint32_t offset) { | 2124 Node* index, uint32_t offset, bool aligned) { |
2126 Node* load; | 2125 Node* load; |
2127 | 2126 |
2128 if (module_ && module_->asm_js()) { | 2127 if (module_ && module_->asm_js()) { |
2129 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). | 2128 // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). |
2130 DCHECK_EQ(0, offset); | 2129 DCHECK_EQ(0, offset); |
2131 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); | 2130 const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); |
2132 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, | 2131 load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, |
2133 *control_); | 2132 *control_); |
2134 } else { | 2133 } else { |
2135 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2134 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2136 BoundsCheckMem(memtype, index, offset); | 2135 BoundsCheckMem(memtype, index, offset); |
2137 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 2136 if (aligned) { |
2138 MemBuffer(offset), index, *effect_, *control_); | 2137 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
| 2138 MemBuffer(offset), index, *effect_, *control_); |
| 2139 } else { |
| 2140 load = graph()->NewNode(jsgraph()->machine()->UnalignedLoad(memtype), |
| 2141 MemBuffer(offset), index, *effect_, *control_); |
| 2142 } |
2139 } | 2143 } |
2140 | 2144 |
2141 *effect_ = load; | 2145 *effect_ = load; |
2142 | 2146 |
2143 if (type == wasm::kAstI64 && | 2147 if (type == wasm::kAstI64 && |
2144 ElementSizeLog2Of(memtype.representation()) < 3) { | 2148 ElementSizeLog2Of(memtype.representation()) < 3) { |
2145 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. | 2149 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. |
2146 if (memtype.IsSigned()) { | 2150 if (memtype.IsSigned()) { |
2147 // sign extend | 2151 // sign extend |
2148 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); | 2152 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); |
2149 } else { | 2153 } else { |
2150 // zero extend | 2154 // zero extend |
2151 load = | 2155 load = |
2152 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); | 2156 graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load); |
2153 } | 2157 } |
2154 } | 2158 } |
2155 | 2159 |
2156 return load; | 2160 return load; |
2157 } | 2161 } |
2158 | 2162 |
2159 | |
2160 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 2163 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
2161 uint32_t offset, Node* val) { | 2164 uint32_t offset, bool aligned, Node* val) { |
2162 Node* store; | 2165 Node* store; |
2163 if (module_ && module_->asm_js()) { | 2166 if (module_ && module_->asm_js()) { |
2164 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). | 2167 // asm.js semantics use CheckedStore (i.e. ignore OOB writes). |
2165 DCHECK_EQ(0, offset); | 2168 DCHECK_EQ(0, offset); |
2166 const Operator* op = | 2169 const Operator* op = |
2167 jsgraph()->machine()->CheckedStore(memtype.representation()); | 2170 jsgraph()->machine()->CheckedStore(memtype.representation()); |
2168 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, | 2171 store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, |
2169 *control_); | 2172 *control_); |
2170 } else { | 2173 } else { |
2171 // WASM semantics throw on OOB. Introduce explicit bounds check. | 2174 // WASM semantics throw on OOB. Introduce explicit bounds check. |
2172 BoundsCheckMem(memtype, index, offset); | 2175 BoundsCheckMem(memtype, index, offset); |
2173 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 2176 if (aligned) { |
2174 store = | 2177 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
2175 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), | 2178 store = |
2176 index, val, *effect_, *control_); | 2179 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |
| 2180 index, val, *effect_, *control_); |
| 2181 } else { |
| 2182 store = graph()->NewNode( |
| 2183 jsgraph()->machine()->UnalignedStore(memtype.representation()), |
| 2184 MemBuffer(offset), index, val, *effect_, *control_); |
| 2185 } |
2177 } | 2186 } |
2178 *effect_ = store; | 2187 *effect_ = store; |
2179 return store; | 2188 return store; |
2180 } | 2189 } |
2181 | 2190 |
2182 | 2191 |
2183 void WasmGraphBuilder::PrintDebugName(Node* node) { | 2192 void WasmGraphBuilder::PrintDebugName(Node* node) { |
2184 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); | 2193 PrintF("#%d:%s", node->id(), node->op()->mnemonic()); |
2185 } | 2194 } |
2186 | 2195 |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 module_env->module->GetName(function.name_offset)); | 2481 module_env->module->GetName(function.name_offset)); |
2473 } | 2482 } |
2474 | 2483 |
2475 return code; | 2484 return code; |
2476 } | 2485 } |
2477 | 2486 |
2478 | 2487 |
2479 } // namespace compiler | 2488 } // namespace compiler |
2480 } // namespace internal | 2489 } // namespace internal |
2481 } // namespace v8 | 2490 } // namespace v8 |
OLD | NEW |