Chromium Code Reviews| 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 <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 | 9 |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 kSourceSize, // Smi. an uint32_t | 95 kSourceSize, // Smi. an uint32_t |
| 96 kWasmSegmentInfoSize // Sentinel value. | 96 kWasmSegmentInfoSize // Sentinel value. |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 enum WasmIndirectFunctionTableData { | 99 enum WasmIndirectFunctionTableData { |
| 100 kSize, // Smi. an uint32_t | 100 kSize, // Smi. an uint32_t |
| 101 kTable, // FixedArray of indirect function table | 101 kTable, // FixedArray of indirect function table |
| 102 kWasmIndirectFunctionTableDataSize // Sentinel value. | 102 kWasmIndirectFunctionTableDataSize // Sentinel value. |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 enum WasmMemoryObjectData { | |
|
titzer
2016/10/11 08:30:06
I am wondering if it is possible to hide these in
gdeepti
2016/10/16 15:39:58
Done.
| |
| 106 kWasmMemoryBuffer, | |
| 107 kWasmMaxMemory, | |
| 108 kWasmInstanceObject | |
| 109 }; | |
| 110 | |
| 105 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { | 111 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { |
| 106 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; | 112 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; |
| 107 } | 113 } |
| 108 | 114 |
| 109 uint32_t GetMinModuleMemSize(const WasmModule* module) { | 115 uint32_t GetMinModuleMemSize(const WasmModule* module) { |
| 110 return WasmModule::kPageSize * module->min_mem_pages; | 116 return WasmModule::kPageSize * module->min_mem_pages; |
| 111 } | 117 } |
| 112 | 118 |
| 113 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, | 119 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, |
| 114 Handle<WasmCompiledModule> compiled_module) { | 120 Handle<WasmCompiledModule> compiled_module) { |
| (...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1442 module_object_->SetInternalField(0, *compiled_module_); | 1448 module_object_->SetInternalField(0, *compiled_module_); |
| 1443 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); | 1449 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); |
| 1444 compiled_module_->set_weak_owning_instance(link_to_owning_instance); | 1450 compiled_module_->set_weak_owning_instance(link_to_owning_instance); |
| 1445 GlobalHandles::MakeWeak(global_handle.location(), | 1451 GlobalHandles::MakeWeak(global_handle.location(), |
| 1446 global_handle.location(), &InstanceFinalizer, | 1452 global_handle.location(), &InstanceFinalizer, |
| 1447 v8::WeakCallbackType::kFinalizer); | 1453 v8::WeakCallbackType::kFinalizer); |
| 1448 } | 1454 } |
| 1449 } | 1455 } |
| 1450 | 1456 |
| 1451 DCHECK(wasm::IsWasmObject(*instance)); | 1457 DCHECK(wasm::IsWasmObject(*instance)); |
| 1458 // TODO(gdeepti): This should be a weak list of instance objects | |
| 1459 // for instances that share memory. | |
| 1460 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | |
| 1461 isolate_); | |
| 1462 if (!memory_object->IsUndefined(isolate_)) { | |
| 1463 JSObject::cast(*memory_object) | |
| 1464 ->SetInternalField(kWasmInstanceObject, *instance); | |
| 1465 } | |
| 1452 | 1466 |
| 1453 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1467 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
| 1454 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1468 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
| 1455 return instance; | 1469 return instance; |
| 1456 } | 1470 } |
| 1457 | 1471 |
| 1458 private: | 1472 private: |
| 1459 Isolate* isolate_; | 1473 Isolate* isolate_; |
| 1460 ErrorThrower* thrower_; | 1474 ErrorThrower* thrower_; |
| 1461 Handle<JSObject> module_object_; | 1475 Handle<JSObject> module_object_; |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2174 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2188 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2175 GetInstanceMemory(isolate, instance); | 2189 GetInstanceMemory(isolate, instance); |
| 2176 Handle<JSArrayBuffer> buffer; | 2190 Handle<JSArrayBuffer> buffer; |
| 2177 if (!maybe_mem_buffer.ToHandle(&buffer)) { | 2191 if (!maybe_mem_buffer.ToHandle(&buffer)) { |
| 2178 return 0; | 2192 return 0; |
| 2179 } else { | 2193 } else { |
| 2180 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2194 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
| 2181 } | 2195 } |
| 2182 } | 2196 } |
| 2183 | 2197 |
| 2198 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { | |
| 2199 uint32_t max_pages = WasmModule::kMaxMemPages; | |
| 2200 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | |
| 2201 isolate); | |
| 2202 if (memory_object->IsUndefined(isolate)) return max_pages; | |
| 2203 Object* max_mem = | |
| 2204 JSObject::cast(*memory_object)->GetInternalField(kWasmMaxMemory); | |
| 2205 if (max_mem->IsUndefined(isolate)) return max_pages; | |
| 2206 max_pages = Smi::cast(max_mem)->value(); | |
| 2207 DCHECK(max_pages <= WasmModule::kMaxMemPages); | |
| 2208 return max_pages; | |
| 2209 } | |
| 2210 | |
| 2184 int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, | 2211 int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
| 2185 uint32_t pages) { | 2212 uint32_t pages) { |
| 2186 if (pages == 0) { | 2213 if (!IsWasmObject(*instance)) return -1; |
| 2187 return GetInstanceMemorySize(isolate, instance); | 2214 if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
| 2188 } | 2215 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); |
| 2216 if (WasmModule::kMaxMemPages < max_pages) return -1; | |
| 2217 | |
| 2189 Address old_mem_start = nullptr; | 2218 Address old_mem_start = nullptr; |
| 2190 uint32_t old_size = 0, new_size = 0; | 2219 uint32_t old_size = 0, new_size = 0; |
| 2191 | 2220 |
| 2192 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 2221 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2193 GetInstanceMemory(isolate, instance); | 2222 GetInstanceMemory(isolate, instance); |
| 2194 Handle<JSArrayBuffer> old_buffer; | 2223 Handle<JSArrayBuffer> old_buffer; |
| 2195 if (!maybe_mem_buffer.ToHandle(&old_buffer)) { | 2224 if (!maybe_mem_buffer.ToHandle(&old_buffer)) { |
| 2196 // If module object does not have linear memory associated with it, | 2225 // If module object does not have linear memory associated with it, |
| 2197 // Allocate new array buffer of given size. | 2226 // Allocate new array buffer of given size. |
| 2198 // TODO(gdeepti): Fix bounds check to take into account size of memtype. | 2227 // TODO(gdeepti): Fix bounds check to take into account size of memtype. |
| 2199 new_size = pages * WasmModule::kPageSize; | 2228 new_size = pages * WasmModule::kPageSize; |
| 2200 // The code generated in the wasm compiler guarantees this precondition. | 2229 if (max_pages < pages) return -1; |
| 2201 DCHECK(pages <= WasmModule::kMaxMemPages); | |
| 2202 } else { | 2230 } else { |
| 2203 old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 2231 old_mem_start = static_cast<Address>(old_buffer->backing_store()); |
| 2204 old_size = old_buffer->byte_length()->Number(); | 2232 old_size = old_buffer->byte_length()->Number(); |
| 2205 // If the old memory was zero-sized, we should have been in the | 2233 // If the old memory was zero-sized, we should have been in the |
| 2206 // "undefined" case above. | 2234 // "undefined" case above. |
| 2207 DCHECK_NOT_NULL(old_mem_start); | 2235 DCHECK_NOT_NULL(old_mem_start); |
| 2208 DCHECK_NE(0, old_size); | 2236 DCHECK_NE(0, old_size); |
| 2209 DCHECK(old_size + pages * WasmModule::kPageSize <= | 2237 DCHECK(old_size + pages * WasmModule::kPageSize <= |
| 2210 std::numeric_limits<uint32_t>::max()); | 2238 std::numeric_limits<uint32_t>::max()); |
| 2211 new_size = old_size + pages * WasmModule::kPageSize; | 2239 new_size = old_size + pages * WasmModule::kPageSize; |
| 2212 } | 2240 } |
| 2213 | 2241 |
| 2214 if (new_size <= old_size || | 2242 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size) { |
| 2215 WasmModule::kMaxMemPages * WasmModule::kPageSize <= new_size) { | |
| 2216 return -1; | 2243 return -1; |
| 2217 } | 2244 } |
| 2218 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); | 2245 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); |
| 2219 if (buffer.is_null()) return -1; | 2246 if (buffer.is_null()) return -1; |
| 2220 Address new_mem_start = static_cast<Address>(buffer->backing_store()); | 2247 Address new_mem_start = static_cast<Address>(buffer->backing_store()); |
| 2221 if (old_size != 0) { | 2248 if (old_size != 0) { |
| 2222 memcpy(new_mem_start, old_mem_start, old_size); | 2249 memcpy(new_mem_start, old_mem_start, old_size); |
| 2223 } | 2250 } |
| 2224 SetInstanceMemory(instance, *buffer); | 2251 SetInstanceMemory(instance, *buffer); |
| 2225 if (!UpdateWasmModuleMemory(instance, old_mem_start, new_mem_start, old_size, | 2252 if (!UpdateWasmModuleMemory(instance, old_mem_start, new_mem_start, old_size, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2277 WasmCompiledModule* compiled_module = | 2304 WasmCompiledModule* compiled_module = |
| 2278 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); | 2305 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); |
| 2279 CHECK(compiled_module->has_weak_module_object()); | 2306 CHECK(compiled_module->has_weak_module_object()); |
| 2280 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2307 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
| 2281 } | 2308 } |
| 2282 | 2309 |
| 2283 } // namespace testing | 2310 } // namespace testing |
| 2284 } // namespace wasm | 2311 } // namespace wasm |
| 2285 } // namespace internal | 2312 } // namespace internal |
| 2286 } // namespace v8 | 2313 } // namespace v8 |
| OLD | NEW |