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

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

Issue 2493823003: [wasm] Allocate a single script per wasm module (Closed)
Patch Set: rebase Created 4 years, 1 month 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') | src/wasm/wasm-objects.h » ('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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { 45 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) {
46 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; 46 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset;
47 } 47 }
48 48
49 MaybeHandle<String> ExtractStringFromModuleBytes( 49 MaybeHandle<String> ExtractStringFromModuleBytes(
50 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, 50 Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
51 uint32_t offset, uint32_t size) { 51 uint32_t offset, uint32_t size) {
52 // TODO(wasm): cache strings from modules if it's a performance win. 52 // TODO(wasm): cache strings from modules if it's a performance win.
53 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); 53 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes();
54 DCHECK_GE(static_cast<size_t>(module_bytes->length()), offset);
55 DCHECK_GE(static_cast<size_t>(module_bytes->length() - offset), size);
54 Address raw = module_bytes->GetCharsAddress() + offset; 56 Address raw = module_bytes->GetCharsAddress() + offset;
55 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) 57 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size))
56 return {}; // UTF8 decoding error for name. 58 return {}; // UTF8 decoding error for name.
57 return isolate->factory()->NewStringFromUtf8SubString( 59 return isolate->factory()->NewStringFromUtf8SubString(
58 module_bytes, static_cast<int>(offset), static_cast<int>(size)); 60 module_bytes, static_cast<int>(offset), static_cast<int>(size));
59 } 61 }
60 62
61 void ReplaceReferenceInCode(Handle<Code> code, Handle<Object> old_ref, 63 void ReplaceReferenceInCode(Handle<Code> code, Handle<Object> old_ref,
62 Handle<Object> new_ref) { 64 Handle<Object> new_ref) {
63 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); 65 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 578 }
577 TRACE("chain after {\n"); 579 TRACE("chain after {\n");
578 TRACE_CHAIN(WasmCompiledModule::cast(wasm_module->GetInternalField(0))); 580 TRACE_CHAIN(WasmCompiledModule::cast(wasm_module->GetInternalField(0)));
579 TRACE("}\n"); 581 TRACE("}\n");
580 } 582 }
581 compiled_module->reset_weak_owning_instance(); 583 compiled_module->reset_weak_owning_instance();
582 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); 584 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
583 TRACE("}\n"); 585 TRACE("}\n");
584 } 586 }
585 587
588 std::pair<int, int> GetFunctionOffsetAndLength(
589 Handle<WasmCompiledModule> compiled_module, int func_index) {
590 WasmModule* module = compiled_module->module();
591 if (func_index < 0 ||
592 static_cast<size_t>(func_index) > module->functions.size()) {
593 return {0, 0};
594 }
595 WasmFunction& func = module->functions[func_index];
596 return {static_cast<int>(func.code_start_offset),
597 static_cast<int>(func.code_end_offset - func.code_start_offset)};
598 }
599
586 } // namespace 600 } // namespace
587 601
588 const char* wasm::SectionName(WasmSectionCode code) { 602 const char* wasm::SectionName(WasmSectionCode code) {
589 switch (code) { 603 switch (code) {
590 case kUnknownSectionCode: 604 case kUnknownSectionCode:
591 return "Unknown"; 605 return "Unknown";
592 case kTypeSectionCode: 606 case kTypeSectionCode:
593 return "Type"; 607 return "Type";
594 case kImportSectionCode: 608 case kImportSectionCode:
595 return "Import"; 609 return "Import";
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 DisallowHeapAllocation no_gc; 671 DisallowHeapAllocation no_gc;
658 FixedArray* deopt_data = code->deoptimization_data(); 672 FixedArray* deopt_data = code->deoptimization_data();
659 DCHECK_NOT_NULL(deopt_data); 673 DCHECK_NOT_NULL(deopt_data);
660 DCHECK(deopt_data->length() == 2); 674 DCHECK(deopt_data->length() == 2);
661 Object* weak_link = deopt_data->get(0); 675 Object* weak_link = deopt_data->get(0);
662 if (!weak_link->IsWeakCell()) return nullptr; 676 if (!weak_link->IsWeakCell()) return nullptr;
663 WeakCell* cell = WeakCell::cast(weak_link); 677 WeakCell* cell = WeakCell::cast(weak_link);
664 return cell->value(); 678 return cell->value();
665 } 679 }
666 680
667 int wasm::GetNumImportedFunctions(Handle<JSObject> object) { 681 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
668 return static_cast<int>(Handle<WasmInstanceObject>::cast(object) 682 int func_index) {
669 ->module() 683 return GetFunctionOffsetAndLength(compiled_module, func_index).first;
670 ->num_imported_functions); 684 }
685
686 bool wasm::GetPositionInfo(Handle<WasmCompiledModule> compiled_module,
687 uint32_t position, Script::PositionInfo* info) {
688 std::vector<WasmFunction>& functions = compiled_module->module()->functions;
689
690 // Binary search for a function containing the given position.
691 int left = 0; // inclusive
692 int right = static_cast<int>(functions.size()); // exclusive
693 if (right == 0) return false;
694 while (right - left > 1) {
695 int mid = left + (right - left) / 2;
696 if (functions[mid].code_start_offset <= position) {
697 left = mid;
698 } else {
699 right = mid;
700 }
701 }
702 // If the found entry does not contains the given position, return false.
703 WasmFunction& func = functions[left];
704 if (position < func.code_start_offset || position >= func.code_end_offset) {
705 return false;
706 }
707
708 info->line = left;
709 info->column = position - func.code_start_offset;
710 info->line_start = func.code_start_offset;
711 info->line_end = func.code_end_offset;
712 return true;
671 } 713 }
672 714
673 WasmModule::WasmModule(Zone* owned, const byte* module_start) 715 WasmModule::WasmModule(Zone* owned, const byte* module_start)
674 : owned_zone(owned), 716 : owned_zone(owned),
675 module_start(module_start), 717 module_start(module_start),
676 pending_tasks(new base::Semaphore(0)) {} 718 pending_tasks(new base::Semaphore(0)) {}
677 719
678 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( 720 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
679 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, 721 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper,
680 ErrorThrower* thrower) const { 722 ErrorThrower* thrower) const {
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 // WebAssembly.Module. 1835 // WebAssembly.Module.
1794 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, 1836 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
1795 ErrorThrower* thrower, 1837 ErrorThrower* thrower,
1796 Handle<JSObject> wasm_module, 1838 Handle<JSObject> wasm_module,
1797 Handle<JSReceiver> ffi, 1839 Handle<JSReceiver> ffi,
1798 Handle<JSArrayBuffer> memory) { 1840 Handle<JSArrayBuffer> memory) {
1799 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); 1841 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
1800 return builder.Build(); 1842 return builder.Build();
1801 } 1843 }
1802 1844
1803 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate,
1804 Handle<Object> object,
1805 uint32_t func_index) {
1806 if (!object->IsUndefined(isolate)) {
1807 auto instance = Handle<WasmInstanceObject>::cast(object);
1808 WasmModule* module = instance->module();
1809 WasmFunction& function = module->functions[func_index];
1810 Handle<WasmCompiledModule> compiled_module(instance->get_compiled_module(),
1811 isolate);
1812 MaybeHandle<String> string = ExtractStringFromModuleBytes(
1813 isolate, compiled_module, function.name_offset, function.name_length);
1814 if (!string.is_null()) return string.ToHandleChecked();
1815 }
1816 return isolate->factory()->null_value();
1817 }
1818
1819 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, 1845 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate,
1820 Handle<Object> instance, 1846 Handle<Object> instance_or_undef,
1821 uint32_t func_index) { 1847 uint32_t func_index) {
1822 Handle<Object> name_or_null = 1848 if (!instance_or_undef->IsUndefined(isolate)) {
1823 GetWasmFunctionNameOrNull(isolate, instance, func_index); 1849 Handle<WasmCompiledModule> compiled_module(
1824 if (!name_or_null->IsNull(isolate)) { 1850 Handle<WasmInstanceObject>::cast(instance_or_undef)
1825 return Handle<String>::cast(name_or_null); 1851 ->get_compiled_module());
1852 MaybeHandle<String> maybe_name =
1853 WasmCompiledModule::GetFunctionName(compiled_module, func_index);
1854 if (!maybe_name.is_null()) return maybe_name.ToHandleChecked();
1826 } 1855 }
1827 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); 1856 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>");
1828 } 1857 }
1829 1858
1830 bool wasm::IsWasmInstance(Object* object) { 1859 bool wasm::IsWasmInstance(Object* object) {
1831 return WasmInstanceObject::IsWasmInstanceObject(object); 1860 return WasmInstanceObject::IsWasmInstanceObject(object);
1832 } 1861 }
1833 1862
1834 WasmCompiledModule* wasm::GetCompiledModule(Object* object) { 1863 WasmCompiledModule* wasm::GetCompiledModule(Object* object) {
1835 return WasmInstanceObject::cast(object)->get_compiled_module(); 1864 return WasmInstanceObject::cast(object)->get_compiled_module();
1836 } 1865 }
1837 1866
1838 bool wasm::WasmIsAsmJs(Object* object, Isolate* isolate) { 1867 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) {
1839 return IsWasmInstance(object) && 1868 if (instance->IsUndefined(isolate)) return false;
1840 WasmInstanceObject::cast(object) 1869 DCHECK(IsWasmInstance(instance));
1841 ->get_compiled_module() 1870 WasmCompiledModule* compiled_module =
1842 ->has_asm_js_script(); 1871 GetCompiledModule(JSObject::cast(instance));
1872 DCHECK_EQ(compiled_module->has_asm_js_offset_tables(),
1873 compiled_module->script()->type() == Script::TYPE_NORMAL);
1874 return compiled_module->has_asm_js_offset_tables();
1843 } 1875 }
1844 1876
1845 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> object) { 1877 Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
1846 return Handle<WasmInstanceObject>::cast(object) 1878 DCHECK(IsWasmInstance(*instance));
1847 ->get_compiled_module() 1879 WasmCompiledModule* compiled_module = GetCompiledModule(*instance);
1848 ->asm_js_script(); 1880 DCHECK(compiled_module->has_script());
1881 return compiled_module->script();
1849 } 1882 }
1850 1883
1851 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, 1884 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index,
1852 int byte_offset) { 1885 int byte_offset) {
1853 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), 1886 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance),
1854 func_index, byte_offset); 1887 func_index, byte_offset);
1855 } 1888 }
1856 1889
1857 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> object) { 1890 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> object) {
1858 return Handle<WasmInstanceObject>::cast(object) 1891 return Handle<WasmInstanceObject>::cast(object)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 // Compile the functions of the module, producing a compiled module. 1931 // Compile the functions of the module, producing a compiled module.
1899 MaybeHandle<WasmCompiledModule> maybe_compiled_module = 1932 MaybeHandle<WasmCompiledModule> maybe_compiled_module =
1900 result.val->CompileFunctions(isolate, module_wrapper, thrower); 1933 result.val->CompileFunctions(isolate, module_wrapper, thrower);
1901 1934
1902 if (maybe_compiled_module.is_null()) return nothing; 1935 if (maybe_compiled_module.is_null()) return nothing;
1903 1936
1904 Handle<WasmCompiledModule> compiled_module = 1937 Handle<WasmCompiledModule> compiled_module =
1905 maybe_compiled_module.ToHandleChecked(); 1938 maybe_compiled_module.ToHandleChecked();
1906 1939
1907 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); 1940 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null());
1908 DCHECK(!compiled_module->has_asm_js_script()); 1941 DCHECK(!compiled_module->has_script());
1909 DCHECK(!compiled_module->has_asm_js_offset_tables()); 1942 DCHECK(!compiled_module->has_asm_js_offset_tables());
1910 if (origin == kAsmJsOrigin) { 1943 if (origin == kAsmJsOrigin) {
1911 compiled_module->set_asm_js_script(asm_js_script); 1944 // Set script for the asm.js source, and the offset table mapping wasm byte
1945 // offsets to source positions.
1946 compiled_module->set_script(asm_js_script);
1912 size_t offset_tables_len = 1947 size_t offset_tables_len =
1913 asm_js_offset_tables_end - asm_js_offset_tables_start; 1948 asm_js_offset_tables_end - asm_js_offset_tables_start;
1914 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); 1949 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len);
1915 Handle<ByteArray> offset_tables = 1950 Handle<ByteArray> offset_tables =
1916 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); 1951 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len));
1917 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, 1952 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start,
1918 offset_tables_len); 1953 offset_tables_len);
1919 compiled_module->set_asm_js_offset_tables(offset_tables); 1954 compiled_module->set_asm_js_offset_tables(offset_tables);
1955 } else {
1956 // Create a new Script object representing this wasm module, store it in the
1957 // compiled wasm module, and register it at the debugger.
1958 Handle<Script> script =
1959 isolate->factory()->NewScript(isolate->factory()->empty_string());
1960 script->set_type(Script::TYPE_WASM);
1961
1962 DCHECK_GE(kMaxInt, end - start);
1963 int hash = StringHasher::HashSequentialString(
1964 reinterpret_cast<const char*>(start), static_cast<int>(end - start),
1965 kZeroHashSeed);
1966
1967 const int kBufferSize = 50;
1968 char buffer[kBufferSize];
1969 int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash);
1970 DCHECK(url_chars >= 0 && url_chars < kBufferSize);
1971 MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte(
1972 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars),
1973 TENURED);
1974 script->set_source_url(*url_str.ToHandleChecked());
1975
1976 int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash);
1977 DCHECK(name_chars >= 0 && name_chars < kBufferSize);
1978 MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte(
1979 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars),
1980 TENURED);
1981 script->set_name(*name_str.ToHandleChecked());
1982
1983 script->set_wasm_compiled_module(*compiled_module);
1984 compiled_module->set_script(script);
1985 isolate->debug()->OnAfterCompile(script);
1920 } 1986 }
1921 1987
1922 return WasmModuleObject::New(isolate, compiled_module); 1988 return WasmModuleObject::New(isolate, compiled_module);
1923 } 1989 }
1924 1990
1925 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, 1991 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
1926 const byte* end, ErrorThrower* thrower, 1992 const byte* end, ErrorThrower* thrower,
1927 ModuleOrigin origin) { 1993 ModuleOrigin origin) {
1928 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); 1994 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
1929 if (result.val) { 1995 if (result.val) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 CHECK_NOT_NULL(result.val); 2168 CHECK_NOT_NULL(result.val);
2103 module = const_cast<WasmModule*>(result.val); 2169 module = const_cast<WasmModule*>(result.val);
2104 } 2170 }
2105 2171
2106 Handle<WasmModuleWrapper> module_wrapper = 2172 Handle<WasmModuleWrapper> module_wrapper =
2107 WasmModuleWrapper::New(isolate, module); 2173 WasmModuleWrapper::New(isolate, module);
2108 2174
2109 compiled_module->set_module_wrapper(module_wrapper); 2175 compiled_module->set_module_wrapper(module_wrapper);
2110 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); 2176 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
2111 } 2177 }
2178
2179 MaybeHandle<String> WasmCompiledModule::GetFunctionName(
2180 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) {
2181 DCHECK_LT(func_index, compiled_module->module()->functions.size());
2182 WasmFunction& function = compiled_module->module()->functions[func_index];
2183 Isolate* isolate = compiled_module->GetIsolate();
2184 MaybeHandle<String> string = ExtractStringFromModuleBytes(
2185 isolate, compiled_module, function.name_offset, function.name_length);
2186 if (!string.is_null()) return string.ToHandleChecked();
2187 return {};
2188 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698