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

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

Issue 2390393002: [wasm] tracing for wasm module instances (Closed)
Patch Set: [wasm] tracing for wasm module instances 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-module.h ('k') | no next file » | 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 10 matching lines...) Expand all
21 #include "src/wasm/wasm-js.h" 21 #include "src/wasm/wasm-js.h"
22 #include "src/wasm/wasm-module.h" 22 #include "src/wasm/wasm-module.h"
23 #include "src/wasm/wasm-result.h" 23 #include "src/wasm/wasm-result.h"
24 24
25 #include "src/compiler/wasm-compiler.h" 25 #include "src/compiler/wasm-compiler.h"
26 26
27 namespace v8 { 27 namespace v8 {
28 namespace internal { 28 namespace internal {
29 namespace wasm { 29 namespace wasm {
30 30
31 #define TRACE(...) \
32 do { \
33 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \
34 } while (false)
35
36 #define TRACE_CHAIN(instance) \
37 do { \
38 instance->PrintInstancesChain(); \
39 } while (false)
40
31 namespace { 41 namespace {
32 42
33 static const int kPlaceholderMarker = 1000000000; 43 static const int kPlaceholderMarker = 1000000000;
34 44
35 enum JSFunctionExportInternalField { 45 enum JSFunctionExportInternalField {
36 kInternalModuleInstance, 46 kInternalModuleInstance,
37 kInternalArity, 47 kInternalArity,
38 kInternalSignature 48 kInternalSignature
39 }; 49 };
40 50
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 UPDATE_WRITE_BARRIER, 731 UPDATE_WRITE_BARRIER,
722 SKIP_ICACHE_FLUSH); 732 SKIP_ICACHE_FLUSH);
723 } 733 }
724 } 734 }
725 } 735 }
726 } 736 }
727 } 737 }
728 738
729 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, 739 static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
730 WasmCompiledModule* compiled_module) { 740 WasmCompiledModule* compiled_module) {
741 TRACE("Resetting %d\n", compiled_module->instance_id());
731 Object* undefined = *isolate->factory()->undefined_value(); 742 Object* undefined = *isolate->factory()->undefined_value();
732 uint32_t old_mem_size = compiled_module->has_heap() 743 uint32_t old_mem_size = compiled_module->has_heap()
733 ? compiled_module->mem_size() 744 ? compiled_module->mem_size()
734 : compiled_module->default_mem_size(); 745 : compiled_module->default_mem_size();
735 uint32_t default_mem_size = compiled_module->default_mem_size(); 746 uint32_t default_mem_size = compiled_module->default_mem_size();
736 Object* mem_start = compiled_module->ptr_to_heap(); 747 Object* mem_start = compiled_module->ptr_to_heap();
737 Address old_mem_address = nullptr; 748 Address old_mem_address = nullptr;
738 Address globals_start = 749 Address globals_start =
739 GetGlobalStartAddressFromCodeTemplate(undefined, owner); 750 GetGlobalStartAddressFromCodeTemplate(undefined, owner);
740 751
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 } 785 }
775 } 786 }
776 compiled_module->reset_heap(); 787 compiled_module->reset_heap();
777 } 788 }
778 789
779 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { 790 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
780 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); 791 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
781 JSObject* owner = *p; 792 JSObject* owner = *p;
782 WasmCompiledModule* compiled_module = 793 WasmCompiledModule* compiled_module =
783 WasmCompiledModule::cast(owner->GetInternalField(kWasmCompiledModule)); 794 WasmCompiledModule::cast(owner->GetInternalField(kWasmCompiledModule));
795 TRACE("Finalizing %d {\n", compiled_module->instance_id());
784 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); 796 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
785 DCHECK(compiled_module->has_weak_module_object()); 797 DCHECK(compiled_module->has_weak_module_object());
786 WeakCell* weak_module_obj = compiled_module->ptr_to_weak_module_object(); 798 WeakCell* weak_module_obj = compiled_module->ptr_to_weak_module_object();
787 799
788 // weak_module_obj may have been cleared, meaning the module object 800 // weak_module_obj may have been cleared, meaning the module object
789 // was GC-ed. In that case, there won't be any new instances created, 801 // was GC-ed. In that case, there won't be any new instances created,
790 // and we don't need to maintain the links between instances. 802 // and we don't need to maintain the links between instances.
791 if (!weak_module_obj->cleared()) { 803 if (!weak_module_obj->cleared()) {
792 JSObject* module_obj = JSObject::cast(weak_module_obj->value()); 804 JSObject* module_obj = JSObject::cast(weak_module_obj->value());
793 WasmCompiledModule* current_template = 805 WasmCompiledModule* current_template =
794 WasmCompiledModule::cast(module_obj->GetInternalField(0)); 806 WasmCompiledModule::cast(module_obj->GetInternalField(0));
807
808 TRACE("chain before {\n");
809 TRACE_CHAIN(current_template);
810 TRACE("}\n");
811
795 DCHECK(!current_template->has_weak_prev_instance()); 812 DCHECK(!current_template->has_weak_prev_instance());
796 WeakCell* next = compiled_module->ptr_to_weak_next_instance(); 813 WeakCell* next = compiled_module->ptr_to_weak_next_instance();
797 WeakCell* prev = compiled_module->ptr_to_weak_prev_instance(); 814 WeakCell* prev = compiled_module->ptr_to_weak_prev_instance();
798 815
799 if (current_template == compiled_module) { 816 if (current_template == compiled_module) {
800 if (next == nullptr) { 817 if (next == nullptr) {
801 ResetCompiledModule(isolate, owner, compiled_module); 818 ResetCompiledModule(isolate, owner, compiled_module);
802 } else { 819 } else {
803 DCHECK(next->value()->IsFixedArray()); 820 DCHECK(next->value()->IsFixedArray());
804 module_obj->SetInternalField(0, next->value()); 821 module_obj->SetInternalField(0, next->value());
(...skipping 17 matching lines...) Expand all
822 if (next != nullptr) { 839 if (next != nullptr) {
823 DCHECK(!next->cleared()); 840 DCHECK(!next->cleared());
824 if (prev == nullptr) { 841 if (prev == nullptr) {
825 WasmCompiledModule::cast(next->value())->reset_weak_prev_instance(); 842 WasmCompiledModule::cast(next->value())->reset_weak_prev_instance();
826 } else { 843 } else {
827 WasmCompiledModule::cast(next->value()) 844 WasmCompiledModule::cast(next->value())
828 ->set_ptr_to_weak_prev_instance(prev); 845 ->set_ptr_to_weak_prev_instance(prev);
829 } 846 }
830 } 847 }
831 } 848 }
849 TRACE("chain after {\n");
850 TRACE_CHAIN(WasmCompiledModule::cast(module_obj->GetInternalField(0)));
851 TRACE("}\n");
832 } 852 }
833 compiled_module->reset_weak_owning_instance(); 853 compiled_module->reset_weak_owning_instance();
834 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); 854 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
855 TRACE("}\n");
835 } 856 }
836 857
837 Handle<FixedArray> SetupIndirectFunctionTable( 858 Handle<FixedArray> SetupIndirectFunctionTable(
838 Isolate* isolate, Handle<FixedArray> wasm_functions, 859 Isolate* isolate, Handle<FixedArray> wasm_functions,
839 Handle<FixedArray> indirect_table_template, 860 Handle<FixedArray> indirect_table_template,
840 Handle<FixedArray> tables_to_replace) { 861 Handle<FixedArray> tables_to_replace) {
841 Factory* factory = isolate->factory(); 862 Factory* factory = isolate->factory();
842 Handle<FixedArray> cloned_indirect_tables = 863 Handle<FixedArray> cloned_indirect_tables =
843 factory->CopyFixedArray(indirect_table_template); 864 factory->CopyFixedArray(indirect_table_template);
844 for (int i = 0; i < cloned_indirect_tables->length(); ++i) { 865 for (int i = 0; i < cloned_indirect_tables->length(); ++i) {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 //-------------------------------------------------------------------------- 1200 //--------------------------------------------------------------------------
1180 Handle<WasmCompiledModule> compiled_module; 1201 Handle<WasmCompiledModule> compiled_module;
1181 Handle<FixedArray> code_table; 1202 Handle<FixedArray> code_table;
1182 Handle<FixedArray> old_code_table; 1203 Handle<FixedArray> old_code_table;
1183 Handle<JSObject> owner; 1204 Handle<JSObject> owner;
1184 // If we don't clone, this will be null(). Otherwise, this will 1205 // If we don't clone, this will be null(). Otherwise, this will
1185 // be a weak link to the original. If we lose the original to GC, 1206 // be a weak link to the original. If we lose the original to GC,
1186 // this will be a cleared. We'll link the instances chain last. 1207 // this will be a cleared. We'll link the instances chain last.
1187 MaybeHandle<WeakCell> link_to_original; 1208 MaybeHandle<WeakCell> link_to_original;
1188 1209
1210 TRACE("Starting new module instantiation\n");
1189 { 1211 {
1190 Handle<WasmCompiledModule> original( 1212 Handle<WasmCompiledModule> original(
1191 WasmCompiledModule::cast(module_object->GetInternalField(0)), isolate); 1213 WasmCompiledModule::cast(module_object->GetInternalField(0)), isolate);
1192 // Always make a new copy of the code_table, since the old_code_table 1214 // Always make a new copy of the code_table, since the old_code_table
1193 // may still have placeholders for imports. 1215 // may still have placeholders for imports.
1194 old_code_table = original->code_table(); 1216 old_code_table = original->code_table();
1195 code_table = factory->CopyFixedArray(old_code_table); 1217 code_table = factory->CopyFixedArray(old_code_table);
1196 1218
1197 if (original->has_weak_owning_instance()) { 1219 if (original->has_weak_owning_instance()) {
1198 WeakCell* tmp = original->ptr_to_weak_owning_instance(); 1220 WeakCell* tmp = original->ptr_to_weak_owning_instance();
1199 DCHECK(!tmp->cleared()); 1221 DCHECK(!tmp->cleared());
1200 // There is already an owner, clone everything. 1222 // There is already an owner, clone everything.
1201 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate); 1223 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate);
1202 // Insert the latest clone in front. 1224 // Insert the latest clone in front.
1225 TRACE("Cloning from %d\n", original->instance_id());
1203 compiled_module = WasmCompiledModule::Clone(isolate, original); 1226 compiled_module = WasmCompiledModule::Clone(isolate, original);
1204 // Replace the strong reference to point to the new instance here. 1227 // Replace the strong reference to point to the new instance here.
1205 // This allows any of the other instances, including the original, 1228 // This allows any of the other instances, including the original,
1206 // to be collected. 1229 // to be collected.
1207 module_object->SetInternalField(0, *compiled_module); 1230 module_object->SetInternalField(0, *compiled_module);
1208 compiled_module->set_weak_module_object(original->weak_module_object()); 1231 compiled_module->set_weak_module_object(original->weak_module_object());
1209 link_to_original = factory->NewWeakCell(original); 1232 link_to_original = factory->NewWeakCell(original);
1210 // Don't link to original here. We remember the original 1233 // Don't link to original here. We remember the original
1211 // as a weak link. If that link isn't clear by the time we finish 1234 // as a weak link. If that link isn't clear by the time we finish
1212 // instantiating this instance, then we link it at that time. 1235 // instantiating this instance, then we link it at that time.
(...skipping 13 matching lines...) Expand all
1226 break; 1249 break;
1227 } 1250 }
1228 default: 1251 default:
1229 UNREACHABLE(); 1252 UNREACHABLE();
1230 } 1253 }
1231 } 1254 }
1232 RecordStats(isolate, code_table); 1255 RecordStats(isolate, code_table);
1233 } else { 1256 } else {
1234 // There was no owner, so we can reuse the original. 1257 // There was no owner, so we can reuse the original.
1235 compiled_module = original; 1258 compiled_module = original;
1259 TRACE("Reusing existing instance %d\n", compiled_module->instance_id());
1236 } 1260 }
1237 compiled_module->set_code_table(code_table); 1261 compiled_module->set_code_table(code_table);
1238 } 1262 }
1239 1263
1240 //-------------------------------------------------------------------------- 1264 //--------------------------------------------------------------------------
1241 // Allocate the instance object. 1265 // Allocate the instance object.
1242 //-------------------------------------------------------------------------- 1266 //--------------------------------------------------------------------------
1243 Handle<Map> map = factory->NewMap( 1267 Handle<Map> map = factory->NewMap(
1244 JS_OBJECT_TYPE, 1268 JS_OBJECT_TYPE,
1245 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1269 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1507 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1484 1508
1485 if (retval.is_null()) { 1509 if (retval.is_null()) {
1486 thrower->Error("WASM.instantiateModule(): start function failed"); 1510 thrower->Error("WASM.instantiateModule(): start function failed");
1487 return nothing; 1511 return nothing;
1488 } 1512 }
1489 } 1513 }
1490 1514
1491 DCHECK(wasm::IsWasmObject(*instance)); 1515 DCHECK(wasm::IsWasmObject(*instance));
1492 1516
1493 if (compiled_module->has_weak_module_object()) { 1517 {
1494 instance->SetInternalField(kWasmCompiledModule, *compiled_module);
1495 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); 1518 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance);
1496 1519
1497 Handle<Object> global_handle = isolate->global_handles()->Create(*instance); 1520 Handle<Object> global_handle = isolate->global_handles()->Create(*instance);
1498 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module); 1521 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module);
1499 { 1522 {
1500 DisallowHeapAllocation no_gc; 1523 DisallowHeapAllocation no_gc;
1501 compiled_module->set_weak_owning_instance(link_to_owner); 1524 compiled_module->set_weak_owning_instance(link_to_owner);
1502 Handle<WeakCell> next; 1525 Handle<WeakCell> next;
1503 if (link_to_original.ToHandle(&next) && !next->cleared()) { 1526 if (link_to_original.ToHandle(&next) && !next->cleared()) {
1504 WasmCompiledModule* original = WasmCompiledModule::cast(next->value()); 1527 WasmCompiledModule* original = WasmCompiledModule::cast(next->value());
1505 DCHECK(original->has_weak_owning_instance()); 1528 DCHECK(original->has_weak_owning_instance());
1506 DCHECK(!original->weak_owning_instance()->cleared()); 1529 DCHECK(!original->weak_owning_instance()->cleared());
1507 compiled_module->set_weak_next_instance(next); 1530 compiled_module->set_weak_next_instance(next);
1508 original->set_weak_prev_instance(link_to_clone); 1531 original->set_weak_prev_instance(link_to_clone);
1509 } 1532 }
1533
1534 compiled_module->set_weak_owning_instance(link_to_owner);
1535 instance->SetInternalField(kWasmCompiledModule, *compiled_module);
1510 GlobalHandles::MakeWeak(global_handle.location(), 1536 GlobalHandles::MakeWeak(global_handle.location(),
1511 global_handle.location(), &InstanceFinalizer, 1537 global_handle.location(), &InstanceFinalizer,
1512 v8::WeakCallbackType::kFinalizer); 1538 v8::WeakCallbackType::kFinalizer);
1513 } 1539 }
1514 } 1540 }
1515 1541 TRACE("Finishing instance %d\n", compiled_module->instance_id());
1542 TRACE_CHAIN(WasmCompiledModule::cast(module_object->GetInternalField(0)));
1516 return instance; 1543 return instance;
1517 } 1544 }
1518 1545
1546 #if DEBUG
1547 uint32_t WasmCompiledModule::instance_id_counter_ = 0;
1548 #endif
1549
1519 Handle<WasmCompiledModule> WasmCompiledModule::New(Isolate* isolate, 1550 Handle<WasmCompiledModule> WasmCompiledModule::New(Isolate* isolate,
1520 uint32_t min_memory_pages, 1551 uint32_t min_memory_pages,
1521 uint32_t globals_size, 1552 uint32_t globals_size,
1522 bool export_memory, 1553 bool export_memory,
1523 ModuleOrigin origin) { 1554 ModuleOrigin origin) {
1524 Handle<FixedArray> ret = 1555 Handle<FixedArray> ret =
1525 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); 1556 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
1526 // Globals size is expected to fit into an int without overflow. This is not 1557 // Globals size is expected to fit into an int without overflow. This is not
1527 // supported by the spec at the moment, however, we don't support array 1558 // supported by the spec at the moment, however, we don't support array
1528 // buffer sizes over 1g, so, for now, we avoid alocating a HeapNumber for 1559 // buffer sizes over 1g, so, for now, we avoid alocating a HeapNumber for
1529 // the globals size. The CHECK guards this assumption. 1560 // the globals size. The CHECK guards this assumption.
1530 CHECK_GE(static_cast<int>(globals_size), 0); 1561 CHECK_GE(static_cast<int>(globals_size), 0);
1531 ret->set(kID_min_memory_pages, 1562 ret->set(kID_min_memory_pages,
1532 Smi::FromInt(static_cast<int>(min_memory_pages))); 1563 Smi::FromInt(static_cast<int>(min_memory_pages)));
1533 ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size))); 1564 ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size)));
1534 ret->set(kID_export_memory, Smi::FromInt(static_cast<int>(export_memory))); 1565 ret->set(kID_export_memory, Smi::FromInt(static_cast<int>(export_memory)));
1535 ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin))); 1566 ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin)));
1567 WasmCompiledModule::cast(*ret)->Init();
1536 return handle(WasmCompiledModule::cast(*ret)); 1568 return handle(WasmCompiledModule::cast(*ret));
1537 } 1569 }
1538 1570
1571 void WasmCompiledModule::Init() {
1572 #if DEBUG
1573 set(kID_instance_id, Smi::FromInt(instance_id_counter_++));
1574 TRACE("New compiled module id: %d\n", instance_id());
1575 #endif
1576 }
1577
1578 void WasmCompiledModule::PrintInstancesChain() {
1579 #if DEBUG
1580 if (!FLAG_trace_wasm_instances) return;
1581 for (WasmCompiledModule* current = this; current != nullptr;) {
1582 PrintF("->%d", current->instance_id());
1583 if (current->ptr_to_weak_next_instance() == nullptr) break;
1584 CHECK(!current->ptr_to_weak_next_instance()->cleared());
1585 current =
1586 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value());
1587 }
1588 PrintF("\n");
1589 #endif
1590 }
1591
1539 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, 1592 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm,
1540 uint32_t func_index) { 1593 uint32_t func_index) {
1541 if (!wasm->IsUndefined(isolate)) { 1594 if (!wasm->IsUndefined(isolate)) {
1542 Handle<ByteArray> func_names_arr_obj( 1595 Handle<ByteArray> func_names_arr_obj(
1543 ByteArray::cast(Handle<JSObject>::cast(wasm)->GetInternalField( 1596 ByteArray::cast(Handle<JSObject>::cast(wasm)->GetInternalField(
1544 kWasmFunctionNamesArray)), 1597 kWasmFunctionNamesArray)),
1545 isolate); 1598 isolate);
1546 // TODO(clemens): Extract this from the module bytes; skip whole function 1599 // TODO(clemens): Extract this from the module bytes; skip whole function
1547 // name table. 1600 // name table.
1548 Handle<Object> name; 1601 Handle<Object> name;
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1803 WasmCompiledModule* compiled_module = 1856 WasmCompiledModule* compiled_module =
1804 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); 1857 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule));
1805 CHECK(compiled_module->has_weak_module_object()); 1858 CHECK(compiled_module->has_weak_module_object());
1806 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); 1859 CHECK(compiled_module->ptr_to_weak_module_object()->cleared());
1807 } 1860 }
1808 1861
1809 } // namespace testing 1862 } // namespace testing
1810 } // namespace wasm 1863 } // namespace wasm
1811 } // namespace internal 1864 } // namespace internal
1812 } // namespace v8 1865 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698