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 |