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