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 10 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |