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 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 isolate->counters()->wasm_instantiate_module_time()); | 1248 isolate->counters()->wasm_instantiate_module_time()); |
1249 Factory* factory = isolate->factory(); | 1249 Factory* factory = isolate->factory(); |
1250 | 1250 |
1251 //-------------------------------------------------------------------------- | 1251 //-------------------------------------------------------------------------- |
1252 // Reuse the compiled module (if no owner), otherwise clone. | 1252 // Reuse the compiled module (if no owner), otherwise clone. |
1253 //-------------------------------------------------------------------------- | 1253 //-------------------------------------------------------------------------- |
1254 Handle<FixedArray> compiled_module; | 1254 Handle<FixedArray> compiled_module; |
1255 Handle<FixedArray> code_table; | 1255 Handle<FixedArray> code_table; |
1256 Handle<FixedArray> old_code_table; | 1256 Handle<FixedArray> old_code_table; |
1257 Handle<JSObject> owner; | 1257 Handle<JSObject> owner; |
| 1258 // If we don't clone, this will be null(). Otherwise, this will |
| 1259 // be a weak link to the original. If we lose the original to GC, |
| 1260 // this will be a cleared. We'll link the instances chain last. |
| 1261 MaybeHandle<WeakCell> link_to_original; |
| 1262 |
1258 { | 1263 { |
1259 Handle<FixedArray> original( | 1264 Handle<FixedArray> original( |
1260 FixedArray::cast(module_object->GetInternalField(0)), isolate); | 1265 FixedArray::cast(module_object->GetInternalField(0)), isolate); |
1261 // Always make a new copy of the code_table, since the old_code_table | 1266 // Always make a new copy of the code_table, since the old_code_table |
1262 // may still have placeholders for imports. | 1267 // may still have placeholders for imports. |
1263 old_code_table = original->GetValueChecked<FixedArray>(isolate, kCodeTable); | 1268 old_code_table = original->GetValueChecked<FixedArray>(isolate, kCodeTable); |
1264 code_table = factory->CopyFixedArray(old_code_table); | 1269 code_table = factory->CopyFixedArray(old_code_table); |
1265 | 1270 |
1266 WeakCell* tmp = GetOwningInstance(*original); | 1271 WeakCell* tmp = GetOwningInstance(*original); |
1267 if (tmp != nullptr) { | 1272 if (tmp != nullptr) { |
| 1273 DCHECK(!tmp->cleared()); |
1268 // There is already an owner, clone everything. | 1274 // There is already an owner, clone everything. |
1269 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate); | 1275 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate); |
1270 // Insert the latest clone in front. | 1276 // Insert the latest clone in front. |
1271 compiled_module = factory->CopyFixedArray(original); | 1277 compiled_module = factory->CopyFixedArray(original); |
| 1278 // Replace the strong reference to point to the new instance here. |
| 1279 // This allows any of the other instances, including the original, |
| 1280 // to be collected. |
| 1281 module_object->SetInternalField(0, *compiled_module); |
1272 Handle<WeakCell> weak_link_to_wasm_obj = | 1282 Handle<WeakCell> weak_link_to_wasm_obj = |
1273 original->GetValueChecked<WeakCell>(isolate, kModuleObject); | 1283 original->GetValueChecked<WeakCell>(isolate, kModuleObject); |
1274 | 1284 |
1275 compiled_module->set(kModuleObject, *weak_link_to_wasm_obj); | 1285 compiled_module->set(kModuleObject, *weak_link_to_wasm_obj); |
1276 Handle<WeakCell> link_to_original = factory->NewWeakCell(original); | 1286 link_to_original = factory->NewWeakCell(original); |
1277 compiled_module->set(kNextInstance, *link_to_original); | 1287 // Don't link to original here. We remember the original |
1278 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module); | 1288 // as a weak link. If that link isn't clear by the time we finish |
1279 original->set(kPrevInstance, *link_to_clone); | 1289 // instantiating this instance, then we link it at that time. |
1280 JSObject::cast(weak_link_to_wasm_obj->value()) | 1290 compiled_module->set(kNextInstance, *factory->undefined_value()); |
1281 ->SetInternalField(0, *compiled_module); | |
1282 | 1291 |
1283 // Clone the code for WASM functions and exports. | 1292 // Clone the code for WASM functions and exports. |
1284 for (int i = 0; i < code_table->length(); ++i) { | 1293 for (int i = 0; i < code_table->length(); ++i) { |
1285 Handle<Code> orig_code = code_table->GetValueChecked<Code>(isolate, i); | 1294 Handle<Code> orig_code = code_table->GetValueChecked<Code>(isolate, i); |
1286 switch (orig_code->kind()) { | 1295 switch (orig_code->kind()) { |
1287 case Code::WASM_TO_JS_FUNCTION: | 1296 case Code::WASM_TO_JS_FUNCTION: |
1288 // Imports will be overwritten with newly compiled wrappers. | 1297 // Imports will be overwritten with newly compiled wrappers. |
1289 break; | 1298 break; |
1290 case Code::JS_TO_WASM_FUNCTION: | 1299 case Code::JS_TO_WASM_FUNCTION: |
1291 case Code::WASM_FUNCTION: { | 1300 case Code::WASM_FUNCTION: { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1570 thrower->Error("WASM.instantiateModule(): start function failed"); | 1579 thrower->Error("WASM.instantiateModule(): start function failed"); |
1571 return nothing; | 1580 return nothing; |
1572 } | 1581 } |
1573 } | 1582 } |
1574 | 1583 |
1575 DCHECK(wasm::IsWasmObject(*instance)); | 1584 DCHECK(wasm::IsWasmObject(*instance)); |
1576 | 1585 |
1577 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) { | 1586 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) { |
1578 instance->SetInternalField(kWasmCompiledModule, *compiled_module); | 1587 instance->SetInternalField(kWasmCompiledModule, *compiled_module); |
1579 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); | 1588 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); |
1580 compiled_module->set(kOwningInstance, *link_to_owner); | |
1581 | 1589 |
1582 Handle<Object> global_handle = isolate->global_handles()->Create(*instance); | 1590 Handle<Object> global_handle = isolate->global_handles()->Create(*instance); |
1583 GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(), | 1591 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module); |
1584 &InstanceFinalizer, | 1592 { |
1585 v8::WeakCallbackType::kFinalizer); | 1593 DisallowHeapAllocation no_gc; |
| 1594 compiled_module->set(kOwningInstance, *link_to_owner); |
| 1595 Handle<WeakCell> next; |
| 1596 if (link_to_original.ToHandle(&next) && !next->cleared()) { |
| 1597 FixedArray* original = FixedArray::cast(next->value()); |
| 1598 DCHECK_NOT_NULL(GetOwningInstance(original)); |
| 1599 DCHECK(!GetOwningInstance(original)->cleared()); |
| 1600 compiled_module->set(kNextInstance, *next); |
| 1601 original->set(kPrevInstance, *link_to_clone); |
| 1602 } |
| 1603 GlobalHandles::MakeWeak(global_handle.location(), |
| 1604 global_handle.location(), &InstanceFinalizer, |
| 1605 v8::WeakCallbackType::kFinalizer); |
| 1606 } |
1586 } | 1607 } |
1587 | 1608 |
1588 return instance; | 1609 return instance; |
1589 } | 1610 } |
1590 | 1611 |
1591 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, | 1612 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, |
1592 uint32_t index) { | 1613 uint32_t index) { |
1593 DCHECK(IsValidFunction(index)); | 1614 DCHECK(IsValidFunction(index)); |
1594 // Always make a direct call to whatever is in the table at that location. | 1615 // Always make a direct call to whatever is in the table at that location. |
1595 // A wrapper will be generated for FFI calls. | 1616 // A wrapper will be generated for FFI calls. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 FixedArray* compiled_module = | 1870 FixedArray* compiled_module = |
1850 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule)); | 1871 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule)); |
1851 CHECK_NOT_NULL(GetModuleObject(compiled_module)); | 1872 CHECK_NOT_NULL(GetModuleObject(compiled_module)); |
1852 CHECK(GetModuleObject(compiled_module)->cleared()); | 1873 CHECK(GetModuleObject(compiled_module)->cleared()); |
1853 } | 1874 } |
1854 | 1875 |
1855 } // namespace testing | 1876 } // namespace testing |
1856 } // namespace wasm | 1877 } // namespace wasm |
1857 } // namespace internal | 1878 } // namespace internal |
1858 } // namespace v8 | 1879 } // namespace v8 |
OLD | NEW |