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

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

Issue 2371403003: [wasm] fix for GC during instantiation. (Closed)
Patch Set: 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 | « no previous file | test/mjsunit/regress/wasm/regression-02862.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 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/wasm/regression-02862.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698