Chromium Code Reviews| 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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 } | 622 } |
| 623 TRACE("chain after {\n"); | 623 TRACE("chain after {\n"); |
| 624 TRACE_CHAIN(WasmCompiledModule::cast(wasm_module->GetInternalField(0))); | 624 TRACE_CHAIN(WasmCompiledModule::cast(wasm_module->GetInternalField(0))); |
| 625 TRACE("}\n"); | 625 TRACE("}\n"); |
| 626 } | 626 } |
| 627 compiled_module->reset_weak_owning_instance(); | 627 compiled_module->reset_weak_owning_instance(); |
| 628 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); | 628 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); |
| 629 TRACE("}\n"); | 629 TRACE("}\n"); |
| 630 } | 630 } |
| 631 | 631 |
| 632 std::pair<int, int> GetFunctionOffsetAndLength( | |
| 633 Handle<WasmCompiledModule> compiled_module, int func_index) { | |
| 634 WasmModule* module = compiled_module->cpp_module(); | |
| 635 if (func_index < 0 || | |
| 636 static_cast<size_t>(func_index) > module->functions.size()) { | |
| 637 return {0, 0}; | |
| 638 } | |
| 639 WasmFunction& func = module->functions[func_index]; | |
| 640 return {static_cast<int>(func.code_start_offset), | |
| 641 static_cast<int>(func.code_end_offset - func.code_start_offset)}; | |
| 642 } | |
| 643 | |
| 632 } // namespace | 644 } // namespace |
| 633 | 645 |
| 634 const char* wasm::SectionName(WasmSectionCode code) { | 646 const char* wasm::SectionName(WasmSectionCode code) { |
| 635 switch (code) { | 647 switch (code) { |
| 636 case kUnknownSectionCode: | 648 case kUnknownSectionCode: |
| 637 return "Unknown"; | 649 return "Unknown"; |
| 638 case kTypeSectionCode: | 650 case kTypeSectionCode: |
| 639 return "Type"; | 651 return "Type"; |
| 640 case kImportSectionCode: | 652 case kImportSectionCode: |
| 641 return "Import"; | 653 return "Import"; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 722 DCHECK_NOT_NULL(deopt_data); | 734 DCHECK_NOT_NULL(deopt_data); |
| 723 DCHECK(deopt_data->length() == 2); | 735 DCHECK(deopt_data->length() == 2); |
| 724 Object* weak_link = deopt_data->get(0); | 736 Object* weak_link = deopt_data->get(0); |
| 725 if (!weak_link->IsWeakCell()) return nullptr; | 737 if (!weak_link->IsWeakCell()) return nullptr; |
| 726 WeakCell* cell = WeakCell::cast(weak_link); | 738 WeakCell* cell = WeakCell::cast(weak_link); |
| 727 return cell->value(); | 739 return cell->value(); |
| 728 } | 740 } |
| 729 | 741 |
| 730 WasmModule* GetCppModule(Handle<JSObject> instance) { | 742 WasmModule* GetCppModule(Handle<JSObject> instance) { |
| 731 DCHECK(IsWasmInstance(*instance)); | 743 DCHECK(IsWasmInstance(*instance)); |
| 732 return reinterpret_cast<WasmModuleWrapper*>( | 744 return Handle<WasmModuleWrapper>::cast( |
| 733 *GetCompiledModule(*instance)->module_wrapper()) | 745 GetCompiledModule(*instance)->module_wrapper()) |
| 734 ->get(); | 746 ->get(); |
| 735 } | 747 } |
| 736 | 748 |
| 737 int wasm::GetNumImportedFunctions(Handle<JSObject> instance) { | 749 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, |
| 738 return static_cast<int>(GetCppModule(instance)->num_imported_functions); | 750 int func_index) { |
| 751 return GetFunctionOffsetAndLength(compiled_module, func_index).first; | |
| 752 } | |
| 753 | |
| 754 bool wasm::GetPositionInfo(Handle<WasmCompiledModule> compiled_module, | |
| 755 uint32_t position, Script::PositionInfo* info) { | |
| 756 WasmModule* module = compiled_module->cpp_module(); | |
| 757 | |
| 758 // Binary search for a function containing the given position. | |
| 759 int left = 0; // inclusive | |
| 760 int right = static_cast<int>(module->functions.size()); // exclusive | |
| 761 if (right == 0) return false; | |
| 762 while (right - left > 1) { | |
| 763 int mid = left + (right - left) / 2; | |
| 764 if (module->functions[mid].code_start_offset <= position) { | |
| 765 left = mid; | |
| 766 } else { | |
| 767 right = mid; | |
| 768 } | |
| 769 } | |
| 770 // If the found entry does not contains the given position, return false. | |
|
Yang
2016/11/15 07:42:26
Can this actually happen, if we check upfront that
Clemens Hammacher
2016/11/15 15:04:06
There is a slight gap between functions, precisely
| |
| 771 WasmFunction& func = module->functions[left]; | |
| 772 if (position < func.code_start_offset || position >= func.code_end_offset) { | |
| 773 return false; | |
| 774 } | |
| 775 | |
| 776 info->line = left; | |
| 777 info->column = position - func.code_start_offset; | |
| 778 info->line_start = func.code_start_offset; | |
| 779 info->line_end = func.code_end_offset; | |
| 780 return true; | |
| 739 } | 781 } |
| 740 | 782 |
| 741 WasmModule::WasmModule(Zone* owned, const byte* module_start) | 783 WasmModule::WasmModule(Zone* owned, const byte* module_start) |
| 742 : owned_zone(owned), | 784 : owned_zone(owned), |
| 743 module_start(module_start), | 785 module_start(module_start), |
| 744 pending_tasks(new base::Semaphore(0)) {} | 786 pending_tasks(new base::Semaphore(0)) {} |
| 745 | 787 |
| 746 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( | 788 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( |
| 747 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, | 789 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, |
| 748 ErrorThrower* thrower) const { | 790 ErrorThrower* thrower) const { |
| (...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1913 PrintF("->%d", current->instance_id()); | 1955 PrintF("->%d", current->instance_id()); |
| 1914 if (current->ptr_to_weak_next_instance() == nullptr) break; | 1956 if (current->ptr_to_weak_next_instance() == nullptr) break; |
| 1915 CHECK(!current->ptr_to_weak_next_instance()->cleared()); | 1957 CHECK(!current->ptr_to_weak_next_instance()->cleared()); |
| 1916 current = | 1958 current = |
| 1917 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | 1959 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); |
| 1918 } | 1960 } |
| 1919 PrintF("\n"); | 1961 PrintF("\n"); |
| 1920 #endif | 1962 #endif |
| 1921 } | 1963 } |
| 1922 | 1964 |
| 1923 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, | 1965 Handle<Object> wasm::GetWasmFunctionNameOrNull( |
| 1924 Handle<Object> instance, | 1966 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, |
| 1925 uint32_t func_index) { | 1967 uint32_t func_index) { |
| 1926 if (!instance->IsUndefined(isolate)) { | 1968 WasmModule* module = |
| 1927 DCHECK(IsWasmInstance(*instance)); | 1969 Handle<WasmModuleWrapper>::cast(compiled_module->module_wrapper())->get(); |
| 1928 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); | 1970 DCHECK_LT(func_index, module->functions.size()); |
| 1929 WasmFunction& function = module->functions[func_index]; | 1971 WasmFunction& function = module->functions[func_index]; |
| 1930 Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), | 1972 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
| 1931 isolate); | 1973 isolate, compiled_module, function.name_offset, function.name_length); |
| 1932 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 1974 if (!string.is_null()) return string.ToHandleChecked(); |
| 1933 isolate, compiled_module, function.name_offset, function.name_length); | |
| 1934 if (!string.is_null()) return string.ToHandleChecked(); | |
| 1935 } | |
| 1936 return isolate->factory()->null_value(); | 1975 return isolate->factory()->null_value(); |
| 1937 } | 1976 } |
| 1938 | 1977 |
| 1939 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, | 1978 Handle<String> wasm::GetWasmFunctionName( |
| 1940 Handle<Object> instance, | 1979 Isolate* isolate, Handle<Object> compiled_module_or_undef, |
| 1941 uint32_t func_index) { | 1980 uint32_t func_index) { |
| 1942 Handle<Object> name_or_null = | 1981 if (!compiled_module_or_undef->IsUndefined(isolate)) { |
| 1943 GetWasmFunctionNameOrNull(isolate, instance, func_index); | 1982 Handle<Object> name_or_null = GetWasmFunctionNameOrNull( |
| 1944 if (!name_or_null->IsNull(isolate)) { | 1983 isolate, Handle<WasmCompiledModule>::cast(compiled_module_or_undef), |
| 1945 return Handle<String>::cast(name_or_null); | 1984 func_index); |
| 1985 if (!name_or_null->IsNull(isolate)) { | |
| 1986 return Handle<String>::cast(name_or_null); | |
| 1987 } | |
| 1946 } | 1988 } |
| 1947 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 1989 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
| 1948 } | 1990 } |
| 1949 | 1991 |
| 1950 bool wasm::IsWasmInstance(Object* object) { | 1992 bool wasm::IsWasmInstance(Object* object) { |
| 1951 if (!object->IsJSObject()) return false; | 1993 if (!object->IsJSObject()) return false; |
| 1952 | 1994 |
| 1953 JSObject* obj = JSObject::cast(object); | 1995 JSObject* obj = JSObject::cast(object); |
| 1954 Isolate* isolate = obj->GetIsolate(); | 1996 Isolate* isolate = obj->GetIsolate(); |
| 1955 if (obj->GetInternalFieldCount() != kWasmInstanceInternalFieldCount) { | 1997 if (obj->GetInternalFieldCount() != kWasmInstanceInternalFieldCount) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1967 return true; | 2009 return true; |
| 1968 } | 2010 } |
| 1969 | 2011 |
| 1970 WasmCompiledModule* wasm::GetCompiledModule(Object* instance) { | 2012 WasmCompiledModule* wasm::GetCompiledModule(Object* instance) { |
| 1971 DCHECK(IsWasmInstance(instance)); | 2013 DCHECK(IsWasmInstance(instance)); |
| 1972 return WasmCompiledModule::cast( | 2014 return WasmCompiledModule::cast( |
| 1973 JSObject::cast(instance)->GetInternalField(kWasmCompiledModule)); | 2015 JSObject::cast(instance)->GetInternalField(kWasmCompiledModule)); |
| 1974 } | 2016 } |
| 1975 | 2017 |
| 1976 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { | 2018 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { |
| 1977 return IsWasmInstance(instance) && | 2019 if (instance->IsUndefined(isolate)) return false; |
| 1978 GetCompiledModule(JSObject::cast(instance))->has_asm_js_script(); | 2020 DCHECK(IsWasmInstance(instance)); |
| 2021 WasmCompiledModule* compiled_module = | |
| 2022 GetCompiledModule(JSObject::cast(instance)); | |
| 2023 DCHECK_EQ(compiled_module->has_asm_js_offset_tables(), | |
| 2024 compiled_module->script()->type() == Script::TYPE_NORMAL); | |
| 2025 return compiled_module->has_asm_js_offset_tables(); | |
| 1979 } | 2026 } |
| 1980 | 2027 |
| 1981 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> instance) { | 2028 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
| 1982 DCHECK(IsWasmInstance(*instance)); | 2029 DCHECK(IsWasmInstance(*instance)); |
| 1983 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 2030 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); |
| 1984 return compiled_module->asm_js_script(); | 2031 DCHECK(compiled_module->has_script()); |
| 2032 return compiled_module->script(); | |
| 1985 } | 2033 } |
| 1986 | 2034 |
| 1987 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, | 2035 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, |
| 1988 int byte_offset) { | 2036 int byte_offset) { |
| 1989 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), | 2037 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), |
| 1990 func_index, byte_offset); | 2038 func_index, byte_offset); |
| 1991 } | 2039 } |
| 1992 | 2040 |
| 1993 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> instance) { | 2041 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> instance) { |
| 1994 DCHECK(IsWasmInstance(*instance)); | 2042 DCHECK(IsWasmInstance(*instance)); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2056 // Compile the functions of the module, producing a compiled module. | 2104 // Compile the functions of the module, producing a compiled module. |
| 2057 MaybeHandle<WasmCompiledModule> maybe_compiled_module = | 2105 MaybeHandle<WasmCompiledModule> maybe_compiled_module = |
| 2058 result.val->CompileFunctions(isolate, module_wrapper, thrower); | 2106 result.val->CompileFunctions(isolate, module_wrapper, thrower); |
| 2059 | 2107 |
| 2060 if (maybe_compiled_module.is_null()) return nothing; | 2108 if (maybe_compiled_module.is_null()) return nothing; |
| 2061 | 2109 |
| 2062 Handle<WasmCompiledModule> compiled_module = | 2110 Handle<WasmCompiledModule> compiled_module = |
| 2063 maybe_compiled_module.ToHandleChecked(); | 2111 maybe_compiled_module.ToHandleChecked(); |
| 2064 | 2112 |
| 2065 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); | 2113 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); |
| 2066 DCHECK(!compiled_module->has_asm_js_script()); | 2114 DCHECK(!compiled_module->has_script()); |
| 2067 DCHECK(!compiled_module->has_asm_js_offset_tables()); | 2115 DCHECK(!compiled_module->has_asm_js_offset_tables()); |
| 2068 if (origin == kAsmJsOrigin) { | 2116 if (origin == kAsmJsOrigin) { |
| 2069 compiled_module->set_asm_js_script(asm_js_script); | 2117 // Set script for the asm.js source, and the offset table mapping wasm byte |
| 2118 // offsets to source positions. | |
| 2119 compiled_module->set_script(asm_js_script); | |
| 2070 size_t offset_tables_len = | 2120 size_t offset_tables_len = |
| 2071 asm_js_offset_tables_end - asm_js_offset_tables_start; | 2121 asm_js_offset_tables_end - asm_js_offset_tables_start; |
| 2072 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); | 2122 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); |
| 2073 Handle<ByteArray> offset_tables = | 2123 Handle<ByteArray> offset_tables = |
| 2074 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); | 2124 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); |
| 2075 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, | 2125 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, |
| 2076 offset_tables_len); | 2126 offset_tables_len); |
| 2077 compiled_module->set_asm_js_offset_tables(offset_tables); | 2127 compiled_module->set_asm_js_offset_tables(offset_tables); |
| 2128 } else { | |
| 2129 // Create a new Script object representing this wasm module, store it in the | |
| 2130 // compiled wasm module, and register it at the debugger. | |
| 2131 Handle<Script> script = | |
| 2132 isolate->factory()->NewScript(isolate->factory()->empty_string()); | |
| 2133 script->set_type(Script::TYPE_WASM); | |
| 2134 | |
| 2135 DCHECK_GE(kMaxInt, end - start); | |
| 2136 int hash = StringHasher::HashSequentialString( | |
| 2137 reinterpret_cast<const char*>(start), static_cast<int>(end - start), | |
| 2138 kZeroHashSeed); | |
| 2139 | |
| 2140 char buffer[50]; | |
| 2141 int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash); | |
| 2142 DCHECK(url_chars >= 0 && url_chars < arraysize(buffer)); | |
| 2143 MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte( | |
| 2144 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars), | |
| 2145 TENURED); | |
| 2146 script->set_source_url(*url_str.ToHandleChecked()); | |
| 2147 | |
| 2148 int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash); | |
| 2149 DCHECK(name_chars >= 0 && name_chars < arraysize(buffer)); | |
| 2150 MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte( | |
| 2151 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars), | |
| 2152 TENURED); | |
| 2153 script->set_name(*name_str.ToHandleChecked()); | |
| 2154 | |
| 2155 script->set_wasm_compiled_module(*compiled_module); | |
| 2156 compiled_module->set_script(script); | |
| 2157 isolate->debug()->OnAfterCompile(script); | |
| 2078 } | 2158 } |
| 2079 | 2159 |
| 2080 return CreateWasmModuleObject(isolate, compiled_module, origin); | 2160 return CreateWasmModuleObject(isolate, compiled_module, origin); |
| 2081 } | 2161 } |
| 2082 | 2162 |
| 2083 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, | 2163 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, |
| 2084 const byte* end, ErrorThrower* thrower, | 2164 const byte* end, ErrorThrower* thrower, |
| 2085 ModuleOrigin origin) { | 2165 ModuleOrigin origin) { |
| 2086 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); | 2166 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); |
| 2087 if (result.val) { | 2167 if (result.val) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2259 CHECK_NOT_NULL(result.val); | 2339 CHECK_NOT_NULL(result.val); |
| 2260 module = const_cast<WasmModule*>(result.val); | 2340 module = const_cast<WasmModule*>(result.val); |
| 2261 } | 2341 } |
| 2262 | 2342 |
| 2263 Handle<WasmModuleWrapper> module_wrapper = | 2343 Handle<WasmModuleWrapper> module_wrapper = |
| 2264 WasmModuleWrapper::New(isolate, module); | 2344 WasmModuleWrapper::New(isolate, module); |
| 2265 | 2345 |
| 2266 compiled_module->set_module_wrapper(module_wrapper); | 2346 compiled_module->set_module_wrapper(module_wrapper); |
| 2267 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | 2347 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
| 2268 } | 2348 } |
| OLD | NEW |