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

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

Issue 2538183003: Revert of [wasm] WebAssembly.Memory object can be referenced by multiple Instance objects. (Closed)
Patch Set: Created 4 years 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-module.h ('k') | src/wasm/wasm-objects.h » ('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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 Handle<Object> new_ref) { 65 Handle<Object> new_ref) {
66 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); 66 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
67 it.next()) { 67 it.next()) {
68 if (it.rinfo()->target_object() == *old_ref) { 68 if (it.rinfo()->target_object() == *old_ref) {
69 it.rinfo()->set_target_object(*new_ref); 69 it.rinfo()->set_target_object(*new_ref);
70 } 70 }
71 } 71 }
72 } 72 }
73 73
74 static void MemoryFinalizer(const v8::WeakCallbackInfo<void>& data) { 74 static void MemoryFinalizer(const v8::WeakCallbackInfo<void>& data) {
75 DisallowHeapAllocation no_gc;
76 JSArrayBuffer** p = reinterpret_cast<JSArrayBuffer**>(data.GetParameter()); 75 JSArrayBuffer** p = reinterpret_cast<JSArrayBuffer**>(data.GetParameter());
77 JSArrayBuffer* buffer = *p; 76 JSArrayBuffer* buffer = *p;
78 77
79 void* memory = buffer->backing_store(); 78 void* memory = buffer->backing_store();
80 base::OS::Free(memory, 79 base::OS::Free(memory,
81 RoundUp(kWasmMaxHeapOffset, base::OS::CommitPageSize())); 80 RoundUp(kWasmMaxHeapOffset, base::OS::CommitPageSize()));
82 81
83 data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory( 82 data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(
84 -buffer->byte_length()->Number()); 83 -buffer->byte_length()->Number());
85 84
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 } 549 }
551 if (changed) { 550 if (changed) {
552 Assembler::FlushICache(isolate, code->instruction_start(), 551 Assembler::FlushICache(isolate, code->instruction_start(),
553 code->instruction_size()); 552 code->instruction_size());
554 } 553 }
555 } 554 }
556 } 555 }
557 compiled_module->reset_memory(); 556 compiled_module->reset_memory();
558 } 557 }
559 558
560 static void MemoryInstanceFinalizer(Isolate* isolate,
561 WasmInstanceObject* instance) {
562 DisallowHeapAllocation no_gc;
563 // If the memory object is destroyed, nothing needs to be done here.
564 if (!instance->has_memory_object()) return;
565 Handle<WasmInstanceWrapper> instance_wrapper =
566 handle(instance->get_instance_wrapper());
567 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
568 DCHECK(instance_wrapper->has_instance());
569 bool has_prev = instance_wrapper->has_previous();
570 bool has_next = instance_wrapper->has_next();
571 Handle<WasmMemoryObject> memory_object(instance->get_memory_object());
572
573 if (!has_prev && !has_next) {
574 memory_object->ResetInstancesLink(isolate);
575 return;
576 } else {
577 Handle<WasmInstanceWrapper> next_wrapper, prev_wrapper;
578 if (!has_prev) {
579 Handle<WasmInstanceWrapper> next_wrapper =
580 instance_wrapper->next_wrapper();
581 next_wrapper->reset_previous_wrapper();
582 // As this is the first link in the memory object, destroying
583 // without updating memory object would corrupt the instance chain in
584 // the memory object.
585 memory_object->set_instances_link(*next_wrapper);
586 } else if (!has_next) {
587 instance_wrapper->previous_wrapper()->reset_next_wrapper();
588 } else {
589 DCHECK(has_next && has_prev);
590 Handle<WasmInstanceWrapper> prev_wrapper =
591 instance_wrapper->previous_wrapper();
592 Handle<WasmInstanceWrapper> next_wrapper =
593 instance_wrapper->next_wrapper();
594 prev_wrapper->set_next_wrapper(*next_wrapper);
595 next_wrapper->set_previous_wrapper(*prev_wrapper);
596 }
597 // Reset to avoid dangling pointers
598 instance_wrapper->reset();
599 }
600 }
601
602 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { 559 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
603 DisallowHeapAllocation no_gc;
604 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); 560 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
605 WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p); 561 WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p);
606 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
607 // Is a link to shared memory instances exists, update the list of memory
608 // instances before the instance is destroyed.
609 if (owner->has_instance_wrapper()) MemoryInstanceFinalizer(isolate, owner);
610 WasmCompiledModule* compiled_module = owner->get_compiled_module(); 562 WasmCompiledModule* compiled_module = owner->get_compiled_module();
611 TRACE("Finalizing %d {\n", compiled_module->instance_id()); 563 TRACE("Finalizing %d {\n", compiled_module->instance_id());
564 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
612 DCHECK(compiled_module->has_weak_wasm_module()); 565 DCHECK(compiled_module->has_weak_wasm_module());
613 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module(); 566 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module();
614 567
615 // weak_wasm_module may have been cleared, meaning the module object 568 // weak_wasm_module may have been cleared, meaning the module object
616 // was GC-ed. In that case, there won't be any new instances created, 569 // was GC-ed. In that case, there won't be any new instances created,
617 // and we don't need to maintain the links between instances. 570 // and we don't need to maintain the links between instances.
618 if (!weak_wasm_module->cleared()) { 571 if (!weak_wasm_module->cleared()) {
619 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value()); 572 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value());
620 WasmCompiledModule* current_template = 573 WasmCompiledModule* current_template =
621 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); 574 WasmCompiledModule::cast(wasm_module->GetInternalField(0));
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 ? static_cast<Address>( 1176 ? static_cast<Address>(
1224 compiled_module_->memory()->backing_store()) 1177 compiled_module_->memory()->backing_store())
1225 : nullptr; 1178 : nullptr;
1226 RelocateMemoryReferencesInCode(code_table, old_mem_start, mem_start, 1179 RelocateMemoryReferencesInCode(code_table, old_mem_start, mem_start,
1227 old_mem_size, mem_size); 1180 old_mem_size, mem_size);
1228 compiled_module_->set_memory(memory_); 1181 compiled_module_->set_memory(memory_);
1229 } else { 1182 } else {
1230 LoadDataSegments(nullptr, 0); 1183 LoadDataSegments(nullptr, 0);
1231 } 1184 }
1232 1185
1233 DCHECK(wasm::IsWasmInstance(*instance));
1234 if (instance->has_memory_object()) {
1235 instance->get_memory_object()->AddInstance(isolate_, instance);
1236 }
1237
1238 //-------------------------------------------------------------------------- 1186 //--------------------------------------------------------------------------
1239 // Set up the runtime support for the new instance. 1187 // Set up the runtime support for the new instance.
1240 //-------------------------------------------------------------------------- 1188 //--------------------------------------------------------------------------
1241 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); 1189 Handle<WeakCell> weak_link = factory->NewWeakCell(instance);
1242 1190
1243 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; 1191 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs;
1244 i < code_table->length(); ++i) { 1192 i < code_table->length(); ++i) {
1245 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); 1193 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i);
1246 if (code->kind() == Code::WASM_FUNCTION) { 1194 if (code->kind() == Code::WASM_FUNCTION) {
1247 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); 1195 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 compiled_module_->set_weak_wasm_module( 1246 compiled_module_->set_weak_wasm_module(
1299 original.ToHandleChecked()->weak_wasm_module()); 1247 original.ToHandleChecked()->weak_wasm_module());
1300 } 1248 }
1301 module_object_->SetInternalField(0, *compiled_module_); 1249 module_object_->SetInternalField(0, *compiled_module_);
1302 compiled_module_->set_weak_owning_instance(link_to_owning_instance); 1250 compiled_module_->set_weak_owning_instance(link_to_owning_instance);
1303 GlobalHandles::MakeWeak(global_handle.location(), 1251 GlobalHandles::MakeWeak(global_handle.location(),
1304 global_handle.location(), &InstanceFinalizer, 1252 global_handle.location(), &InstanceFinalizer,
1305 v8::WeakCallbackType::kFinalizer); 1253 v8::WeakCallbackType::kFinalizer);
1306 } 1254 }
1307 } 1255 }
1256
1257 DCHECK(wasm::IsWasmInstance(*instance));
1258 if (instance->has_memory_object()) {
1259 instance->get_memory_object()->AddInstance(*instance);
1260 }
1261
1308 //-------------------------------------------------------------------------- 1262 //--------------------------------------------------------------------------
1309 // Run the start function if one was specified. 1263 // Run the start function if one was specified.
1310 //-------------------------------------------------------------------------- 1264 //--------------------------------------------------------------------------
1311 if (module_->start_function_index >= 0) { 1265 if (module_->start_function_index >= 0) {
1312 HandleScope scope(isolate_); 1266 HandleScope scope(isolate_);
1313 ModuleEnv module_env; 1267 ModuleEnv module_env;
1314 module_env.module = module_; 1268 module_env.module = module_;
1315 module_env.instance = nullptr; 1269 module_env.instance = nullptr;
1316 module_env.origin = module_->origin; 1270 module_env.origin = module_->origin;
1317 int start_index = module_->start_function_index; 1271 int start_index = module_->start_function_index;
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 break; 1546 break;
1593 } 1547 }
1594 case kExternalMemory: { 1548 case kExternalMemory: {
1595 Handle<Object> object = result.ToHandleChecked(); 1549 Handle<Object> object = result.ToHandleChecked();
1596 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { 1550 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) {
1597 ReportFFIError("memory import must be a WebAssembly.Memory object", 1551 ReportFFIError("memory import must be a WebAssembly.Memory object",
1598 index, module_name, function_name); 1552 index, module_name, function_name);
1599 return -1; 1553 return -1;
1600 } 1554 }
1601 auto memory = Handle<WasmMemoryObject>::cast(object); 1555 auto memory = Handle<WasmMemoryObject>::cast(object);
1602 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory));
1603 instance->set_memory_object(*memory); 1556 instance->set_memory_object(*memory);
1604 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); 1557 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_);
1605 break; 1558 break;
1606 } 1559 }
1607 case kExternalGlobal: { 1560 case kExternalGlobal: {
1608 // Global imports are converted to numbers and written into the 1561 // Global imports are converted to numbers and written into the
1609 // {globals_} array buffer. 1562 // {globals_} array buffer.
1610 Handle<Object> object = result.ToHandleChecked(); 1563 Handle<Object> object = result.ToHandleChecked();
1611 MaybeHandle<Object> number = Object::ToNumber(object); 1564 MaybeHandle<Object> number = Object::ToNumber(object);
1612 if (number.is_null()) { 1565 if (number.is_null()) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 // If there was no imported WebAssembly.Memory object, create one. 1727 // If there was no imported WebAssembly.Memory object, create one.
1775 Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(), 1728 Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(),
1776 isolate_); 1729 isolate_);
1777 memory_object = WasmMemoryObject::New( 1730 memory_object = WasmMemoryObject::New(
1778 isolate_, buffer, 1731 isolate_, buffer,
1779 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1); 1732 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1);
1780 instance->set_memory_object(*memory_object); 1733 instance->set_memory_object(*memory_object);
1781 } else { 1734 } else {
1782 memory_object = Handle<WasmMemoryObject>( 1735 memory_object = Handle<WasmMemoryObject>(
1783 instance->get_memory_object(), isolate_); 1736 instance->get_memory_object(), isolate_);
1784 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory_object));
1785 memory_object->ResetInstancesLink(isolate_);
1786 } 1737 }
1787 1738
1788 desc.set_value(memory_object); 1739 desc.set_value(memory_object);
1789 break; 1740 break;
1790 } 1741 }
1791 case kExternalGlobal: { 1742 case kExternalGlobal: {
1792 // Export the value of the global variable as a number. 1743 // Export the value of the global variable as a number.
1793 WasmGlobal& global = module_->globals[exp.index]; 1744 WasmGlobal& global = module_->globals[exp.index];
1794 double num = 0; 1745 double num = 0;
1795 switch (global.type) { 1746 switch (global.type) {
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); 2062 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
2112 if (result.val) { 2063 if (result.val) {
2113 delete result.val; 2064 delete result.val;
2114 } else { 2065 } else {
2115 DCHECK(!result.ok()); 2066 DCHECK(!result.ok());
2116 } 2067 }
2117 return result.ok(); 2068 return result.ok();
2118 } 2069 }
2119 2070
2120 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory( 2071 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
2121 Isolate* isolate, Handle<WasmInstanceObject> object) { 2072 Isolate* isolate, Handle<WasmInstanceObject> instance) {
2122 auto instance = Handle<WasmInstanceObject>::cast(object);
2123 if (instance->has_memory_buffer()) { 2073 if (instance->has_memory_buffer()) {
2124 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate); 2074 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate);
2125 } 2075 }
2126 return MaybeHandle<JSArrayBuffer>(); 2076 return MaybeHandle<JSArrayBuffer>();
2127 } 2077 }
2128 2078
2129 void SetInstanceMemory(Handle<WasmInstanceObject> instance, 2079 void SetInstanceMemory(Handle<WasmInstanceObject> instance,
2130 JSArrayBuffer* buffer) { 2080 JSArrayBuffer* buffer) {
2131 DisallowHeapAllocation no_gc; 2081 DisallowHeapAllocation no_gc;
2132 instance->set_memory_buffer(buffer); 2082 instance->set_memory_buffer(buffer);
2133 instance->get_compiled_module()->set_ptr_to_memory(buffer); 2083 instance->get_compiled_module()->set_ptr_to_memory(buffer);
2134 } 2084 }
2135 2085
2136 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, 2086 int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
2137 Handle<WasmInstanceObject> instance) { 2087 Handle<WasmInstanceObject> instance) {
2138 DCHECK(IsWasmInstance(*instance));
2139 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = 2088 MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
2140 GetInstanceMemory(isolate, instance); 2089 GetInstanceMemory(isolate, instance);
2141 Handle<JSArrayBuffer> buffer; 2090 Handle<JSArrayBuffer> buffer;
2142 if (!maybe_mem_buffer.ToHandle(&buffer)) { 2091 if (!maybe_mem_buffer.ToHandle(&buffer)) {
2143 return 0; 2092 return 0;
2144 } else { 2093 } else {
2145 return buffer->byte_length()->Number() / WasmModule::kPageSize; 2094 return buffer->byte_length()->Number() / WasmModule::kPageSize;
2146 } 2095 }
2147 } 2096 }
2148 2097
2149 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, 2098 uint32_t GetMaxInstanceMemorySize(Isolate* isolate,
2150 Handle<WasmInstanceObject> instance) { 2099 Handle<WasmInstanceObject> instance) {
2151 if (instance->has_memory_object()) { 2100 if (instance->has_memory_object()) {
2152 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(), 2101 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(),
2153 isolate); 2102 isolate);
2154 2103
2155 int maximum = memory_object->maximum_pages(); 2104 int maximum = memory_object->maximum_pages();
2156 if (maximum > 0) return static_cast<uint32_t>(maximum); 2105 if (maximum > 0) return static_cast<uint32_t>(maximum);
2157 } 2106 }
2158 uint32_t compiled_max_pages = 2107 uint32_t compiled_max_pages =
2159 instance->get_compiled_module()->max_mem_pages(); 2108 instance->get_compiled_module()->max_mem_pages();
2160 isolate->counters()->wasm_max_mem_pages_count()->AddSample( 2109 isolate->counters()->wasm_max_mem_pages_count()->AddSample(
2161 compiled_max_pages); 2110 compiled_max_pages);
2162 if (compiled_max_pages != 0) return compiled_max_pages; 2111 if (compiled_max_pages != 0) return compiled_max_pages;
2163 return WasmModule::kV8MaxPages; 2112 return WasmModule::kV8MaxPages;
2164 } 2113 }
2165 2114
2166 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, 2115 int32_t wasm::GrowInstanceMemory(Isolate* isolate,
2167 MaybeHandle<JSArrayBuffer> buffer, 2116 Handle<WasmInstanceObject> instance,
2168 uint32_t pages, uint32_t max_pages) { 2117 uint32_t pages) {
2118 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2119 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
2120
2121 Address old_mem_start = nullptr;
2122 uint32_t old_size = 0, new_size = 0;
2123
2124 MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
2125 GetInstanceMemory(isolate, instance);
2169 Handle<JSArrayBuffer> old_buffer; 2126 Handle<JSArrayBuffer> old_buffer;
2170 Address old_mem_start = nullptr; 2127 if (!maybe_mem_buffer.ToHandle(&old_buffer) ||
2171 uint32_t old_size = 0; 2128 old_buffer->backing_store() == nullptr) {
2172 if (buffer.ToHandle(&old_buffer) && old_buffer->backing_store() != nullptr) { 2129 // If module object does not have linear memory associated with it,
2130 // Allocate new array buffer of given size.
2131 new_size = pages * WasmModule::kPageSize;
2132 if (max_pages < pages) return -1;
2133 } else {
2173 old_mem_start = static_cast<Address>(old_buffer->backing_store()); 2134 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2135 old_size = old_buffer->byte_length()->Number();
2136 // If the old memory was zero-sized, we should have been in the
2137 // "undefined" case above.
2174 DCHECK_NOT_NULL(old_mem_start); 2138 DCHECK_NOT_NULL(old_mem_start);
2175 old_size = old_buffer->byte_length()->Number(); 2139 DCHECK(old_size + pages * WasmModule::kPageSize <=
2140 std::numeric_limits<uint32_t>::max());
2141 new_size = old_size + pages * WasmModule::kPageSize;
2176 } 2142 }
2177 DCHECK(old_size + pages * WasmModule::kPageSize <= 2143
2178 std::numeric_limits<uint32_t>::max());
2179 uint32_t new_size = old_size + pages * WasmModule::kPageSize;
2180 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size || 2144 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size ||
2181 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) { 2145 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) {
2182 return Handle<JSArrayBuffer>::null(); 2146 return -1;
2183 } 2147 }
2184 2148
2185 Handle<JSArrayBuffer> new_buffer; 2149 Handle<JSArrayBuffer> buffer;
2150
2186 if (!old_buffer.is_null() && old_buffer->has_guard_region()) { 2151 if (!old_buffer.is_null() && old_buffer->has_guard_region()) {
2187 // We don't move the backing store, we simply change the protection to make 2152 // We don't move the backing store, we simply change the protection to make
2188 // more of it accessible. 2153 // more of it accessible.
2189 base::OS::Unprotect(old_buffer->backing_store(), new_size); 2154 base::OS::Unprotect(old_buffer->backing_store(), new_size);
2190 reinterpret_cast<v8::Isolate*>(isolate) 2155 reinterpret_cast<v8::Isolate*>(isolate)
2191 ->AdjustAmountOfExternalAllocatedMemory(pages * WasmModule::kPageSize); 2156 ->AdjustAmountOfExternalAllocatedMemory(pages * WasmModule::kPageSize);
2192 Handle<Object> new_size_object = 2157 Handle<Object> new_size_object =
2193 isolate->factory()->NewNumberFromSize(new_size); 2158 isolate->factory()->NewNumberFromSize(new_size);
2194 old_buffer->set_byte_length(*new_size_object); 2159 old_buffer->set_byte_length(*new_size_object);
2195 new_buffer = old_buffer; 2160
2161 SetInstanceMemory(instance, *old_buffer);
2162 Handle<FixedArray> code_table =
2163 instance->get_compiled_module()->code_table();
2164 RelocateMemoryReferencesInCode(code_table, old_mem_start, old_mem_start,
2165 old_size, new_size);
2166 buffer = old_buffer;
2196 } else { 2167 } else {
2197 const bool enable_guard_regions = false; 2168 const bool enable_guard_regions = false;
2198 new_buffer = NewArrayBuffer(isolate, new_size, enable_guard_regions); 2169 buffer = NewArrayBuffer(isolate, new_size, enable_guard_regions);
2199 if (new_buffer.is_null()) return new_buffer; 2170 if (buffer.is_null()) return -1;
2200 Address new_mem_start = static_cast<Address>(new_buffer->backing_store()); 2171 Address new_mem_start = static_cast<Address>(buffer->backing_store());
2201 if (old_size != 0) { 2172 if (old_size != 0) {
2202 memcpy(new_mem_start, old_mem_start, old_size); 2173 memcpy(new_mem_start, old_mem_start, old_size);
2203 } 2174 }
2175 SetInstanceMemory(instance, *buffer);
2176 Handle<FixedArray> code_table =
2177 instance->get_compiled_module()->code_table();
2178 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start,
2179 old_size, new_size);
2204 } 2180 }
2205 return new_buffer;
2206 }
2207 2181
2208 void UncheckedUpdateInstanceMemory(Isolate* isolate, 2182 SetInstanceMemory(instance, *buffer);
2209 Handle<WasmInstanceObject> instance, 2183 if (instance->has_memory_object()) {
2210 Address old_mem_start, uint32_t old_size) { 2184 instance->get_memory_object()->set_buffer(*buffer);
2211 DCHECK(instance->has_memory_buffer()); 2185 }
2212 Handle<JSArrayBuffer> new_buffer(instance->get_memory_buffer());
2213 uint32_t new_size = new_buffer->byte_length()->Number();
2214 DCHECK(new_size <= std::numeric_limits<uint32_t>::max());
2215 Address new_mem_start = static_cast<Address>(new_buffer->backing_store());
2216 DCHECK_NOT_NULL(new_mem_start);
2217 Handle<FixedArray> code_table = instance->get_compiled_module()->code_table();
2218 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start,
2219 old_size, new_size);
2220 }
2221 2186
2222 int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, Handle<Object> receiver,
2223 uint32_t pages) {
2224 DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver));
2225 Handle<WasmMemoryObject> memory_object =
2226 handle(WasmMemoryObject::cast(*receiver));
2227 Handle<WasmInstanceWrapper> instance_wrapper(
2228 memory_object->get_instances_link());
2229 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
2230 DCHECK(instance_wrapper->has_instance());
2231 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
2232 DCHECK(IsWasmInstance(*instance));
2233 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2234 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
2235
2236 // Grow memory object buffer and update instances associated with it.
2237 MaybeHandle<JSArrayBuffer> memory_buffer =
2238 handle(memory_object->get_buffer());
2239 Handle<JSArrayBuffer> old_buffer;
2240 uint32_t old_size = 0;
2241 Address old_mem_start = nullptr;
2242 if (memory_buffer.ToHandle(&old_buffer) &&
2243 old_buffer->backing_store() != nullptr) {
2244 old_size = old_buffer->byte_length()->Number();
2245 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2246 }
2247 Handle<JSArrayBuffer> new_buffer =
2248 GrowMemoryBuffer(isolate, memory_buffer, pages, max_pages);
2249 if (new_buffer.is_null()) return -1;
2250 DCHECK(!instance_wrapper->has_previous());
2251 SetInstanceMemory(instance, *new_buffer);
2252 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
2253 while (instance_wrapper->has_next()) {
2254 instance_wrapper = instance_wrapper->next_wrapper();
2255 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
2256 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
2257 DCHECK(IsWasmInstance(*instance));
2258 SetInstanceMemory(instance, *new_buffer);
2259 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
2260 }
2261 memory_object->set_buffer(*new_buffer);
2262 DCHECK(old_size % WasmModule::kPageSize == 0); 2187 DCHECK(old_size % WasmModule::kPageSize == 0);
2263 return (old_size / WasmModule::kPageSize); 2188 return (old_size / WasmModule::kPageSize);
2264 } 2189 }
2265 2190
2266 int32_t wasm::GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance,
2267 uint32_t pages) {
2268 if (!IsWasmInstance(*instance)) return -1;
2269 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2270 Handle<WasmInstanceObject> instance_obj(WasmInstanceObject::cast(*instance));
2271 if (!instance_obj->has_memory_object()) {
2272 // No other instances to grow, grow just the one.
2273 MaybeHandle<JSArrayBuffer> instance_buffer =
2274 GetInstanceMemory(isolate, instance);
2275 Handle<JSArrayBuffer> old_buffer;
2276 uint32_t old_size = 0;
2277 Address old_mem_start = nullptr;
2278 if (instance_buffer.ToHandle(&old_buffer) &&
2279 old_buffer->backing_store() != nullptr) {
2280 old_size = old_buffer->byte_length()->Number();
2281 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2282 }
2283 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance_obj);
2284 Handle<JSArrayBuffer> buffer =
2285 GrowMemoryBuffer(isolate, instance_buffer, pages, max_pages);
2286 if (buffer.is_null()) return -1;
2287 SetInstanceMemory(instance, *buffer);
2288 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
2289 DCHECK(old_size % WasmModule::kPageSize == 0);
2290 return (old_size / WasmModule::kPageSize);
2291 } else {
2292 return GrowWebAssemblyMemory(
2293 isolate, handle(instance_obj->get_memory_object()), pages);
2294 }
2295 }
2296
2297 void testing::ValidateInstancesChain(Isolate* isolate, 2191 void testing::ValidateInstancesChain(Isolate* isolate,
2298 Handle<WasmModuleObject> module_obj, 2192 Handle<WasmModuleObject> module_obj,
2299 int instance_count) { 2193 int instance_count) {
2300 CHECK_GE(instance_count, 0); 2194 CHECK_GE(instance_count, 0);
2301 DisallowHeapAllocation no_gc; 2195 DisallowHeapAllocation no_gc;
2302 WasmCompiledModule* compiled_module = module_obj->get_compiled_module(); 2196 WasmCompiledModule* compiled_module = module_obj->get_compiled_module();
2303 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()), 2197 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()),
2304 *module_obj); 2198 *module_obj);
2305 Object* prev = nullptr; 2199 Object* prev = nullptr;
2306 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; 2200 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2372 MaybeHandle<String> WasmCompiledModule::GetFunctionName( 2266 MaybeHandle<String> WasmCompiledModule::GetFunctionName(
2373 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { 2267 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) {
2374 DCHECK_LT(func_index, compiled_module->module()->functions.size()); 2268 DCHECK_LT(func_index, compiled_module->module()->functions.size());
2375 WasmFunction& function = compiled_module->module()->functions[func_index]; 2269 WasmFunction& function = compiled_module->module()->functions[func_index];
2376 Isolate* isolate = compiled_module->GetIsolate(); 2270 Isolate* isolate = compiled_module->GetIsolate();
2377 MaybeHandle<String> string = ExtractStringFromModuleBytes( 2271 MaybeHandle<String> string = ExtractStringFromModuleBytes(
2378 isolate, compiled_module, function.name_offset, function.name_length); 2272 isolate, compiled_module, function.name_offset, function.name_length);
2379 if (!string.is_null()) return string.ToHandleChecked(); 2273 if (!string.is_null()) return string.ToHandleChecked();
2380 return {}; 2274 return {};
2381 } 2275 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698