Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2410763002: [wasm] GrowMemory should use maximum size declared in WebAssembly.Memory (Closed)
Patch Set: Separate refactoring, add test Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-js.cc ('k') | test/mjsunit/wasm/import-memory.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/wasm/wasm-js.cc ('k') | test/mjsunit/wasm/import-memory.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698