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

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

Issue 2784453002: [wasm] Fix serialization after instantiation (Closed)
Patch Set: feedback Created 3 years, 8 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-objects.h ('k') | test/mjsunit/wasm/compiled-module-serialization.js » ('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 "src/wasm/wasm-objects.h" 5 #include "src/wasm/wasm-objects.h"
6 #include "src/utils.h" 6 #include "src/utils.h"
7 7
8 #include "src/assembler-inl.h" 8 #include "src/assembler-inl.h"
9 #include "src/base/iterator.h" 9 #include "src/base/iterator.h"
10 #include "src/compiler/wasm-compiler.h" 10 #include "src/compiler/wasm-compiler.h"
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 // WasmCompiledModule::cast would fail since fields are not set yet. 765 // WasmCompiledModule::cast would fail since fields are not set yet.
766 Handle<WasmCompiledModule> compiled_module( 766 Handle<WasmCompiledModule> compiled_module(
767 reinterpret_cast<WasmCompiledModule*>(*ret), isolate); 767 reinterpret_cast<WasmCompiledModule*>(*ret), isolate);
768 compiled_module->InitId(); 768 compiled_module->InitId();
769 compiled_module->set_num_imported_functions(0); 769 compiled_module->set_num_imported_functions(0);
770 compiled_module->set_shared(shared); 770 compiled_module->set_shared(shared);
771 compiled_module->set_native_context(isolate->native_context()); 771 compiled_module->set_native_context(isolate->native_context());
772 return compiled_module; 772 return compiled_module;
773 } 773 }
774 774
775 Handle<WasmCompiledModule> WasmCompiledModule::Clone(
776 Isolate* isolate, Handle<WasmCompiledModule> module) {
777 Handle<WasmCompiledModule> ret = Handle<WasmCompiledModule>::cast(
778 isolate->factory()->CopyFixedArray(module));
779 ret->InitId();
780 ret->reset_weak_owning_instance();
781 ret->reset_weak_next_instance();
782 ret->reset_weak_prev_instance();
783 ret->reset_weak_exported_functions();
784 if (ret->has_embedded_mem_start()) {
785 WasmCompiledModule::recreate_embedded_mem_start(ret, isolate->factory(),
786 ret->embedded_mem_start());
787 }
788 if (ret->has_globals_start()) {
789 WasmCompiledModule::recreate_globals_start(ret, isolate->factory(),
790 ret->globals_start());
791 }
792 if (ret->has_embedded_mem_size()) {
793 WasmCompiledModule::recreate_embedded_mem_size(ret, isolate->factory(),
794 ret->embedded_mem_size());
795 }
796 return ret;
797 }
798
799 void WasmCompiledModule::Reset(Isolate* isolate,
800 WasmCompiledModule* compiled_module) {
801 DisallowHeapAllocation no_gc;
802 TRACE("Resetting %d\n", compiled_module->instance_id());
803 Object* undefined = *isolate->factory()->undefined_value();
804 Object* fct_obj = compiled_module->ptr_to_code_table();
805 if (fct_obj != nullptr && fct_obj != undefined) {
806 uint32_t old_mem_size = compiled_module->mem_size();
807 uint32_t default_mem_size = compiled_module->default_mem_size();
808 Address old_mem_start = compiled_module->GetEmbeddedMemStartOrNull();
809
810 // Patch code to update memory references, global references, and function
811 // table references.
812 Zone specialization_zone(isolate->allocator(), ZONE_NAME);
813 CodeSpecialization code_specialization(isolate, &specialization_zone);
814
815 if (old_mem_size > 0 && old_mem_start != nullptr) {
816 code_specialization.RelocateMemoryReferences(old_mem_start, old_mem_size,
817 nullptr, default_mem_size);
818 }
819
820 if (compiled_module->has_globals_start()) {
821 Address globals_start =
822 reinterpret_cast<Address>(compiled_module->globals_start());
823 code_specialization.RelocateGlobals(globals_start, nullptr);
824 compiled_module->set_globals_start(0);
825 }
826
827 // Reset function tables.
828 if (compiled_module->has_function_tables()) {
829 FixedArray* function_tables = compiled_module->ptr_to_function_tables();
830 FixedArray* empty_function_tables =
831 compiled_module->ptr_to_empty_function_tables();
832 if (function_tables != empty_function_tables) {
833 DCHECK_EQ(function_tables->length(), empty_function_tables->length());
834 for (int i = 0, e = function_tables->length(); i < e; ++i) {
835 code_specialization.RelocateObject(
836 handle(function_tables->get(i), isolate),
837 handle(empty_function_tables->get(i), isolate));
838 }
839 compiled_module->set_ptr_to_function_tables(empty_function_tables);
840 }
841 }
842
843 FixedArray* functions = FixedArray::cast(fct_obj);
844 for (int i = compiled_module->num_imported_functions(),
845 end = functions->length();
846 i < end; ++i) {
847 Code* code = Code::cast(functions->get(i));
848 // Skip lazy compile stubs.
849 if (code->builtin_index() == Builtins::kWasmCompileLazy) continue;
850 if (code->kind() != Code::WASM_FUNCTION) {
851 // From here on, there should only be wrappers for exported functions.
852 for (; i < end; ++i) {
853 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION,
854 Code::cast(functions->get(i))->kind());
855 }
856 break;
857 }
858 bool changed =
859 code_specialization.ApplyToWasmCode(code, SKIP_ICACHE_FLUSH);
860 // TODO(wasm): Check if this is faster than passing FLUSH_ICACHE_IF_NEEDED
861 // above.
862 if (changed) {
863 Assembler::FlushICache(isolate, code->instruction_start(),
864 code->instruction_size());
865 }
866 }
867 }
868 compiled_module->ResetSpecializationMemInfoIfNeeded();
869 }
870
775 void WasmCompiledModule::InitId() { 871 void WasmCompiledModule::InitId() {
776 #if DEBUG 872 #if DEBUG
777 static uint32_t instance_id_counter = 0; 873 static uint32_t instance_id_counter = 0;
778 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); 874 set(kID_instance_id, Smi::FromInt(instance_id_counter++));
779 TRACE("New compiled module id: %d\n", instance_id()); 875 TRACE("New compiled module id: %d\n", instance_id());
780 #endif 876 #endif
781 } 877 }
782 878
879 void WasmCompiledModule::ResetSpecializationMemInfoIfNeeded() {
880 DisallowHeapAllocation no_gc;
881 if (has_embedded_mem_start()) {
882 set_embedded_mem_size(0);
883 set_embedded_mem_start(0);
884 }
885 }
886
887 void WasmCompiledModule::SetSpecializationMemInfoFrom(
888 Factory* factory, Handle<WasmCompiledModule> compiled_module,
889 Handle<JSArrayBuffer> buffer) {
890 DCHECK(!buffer.is_null());
891 size_t start_address = reinterpret_cast<size_t>(buffer->backing_store());
892 uint32_t size = static_cast<uint32_t>(buffer->byte_length()->Number());
893 if (!compiled_module->has_embedded_mem_start()) {
894 DCHECK(!compiled_module->has_embedded_mem_size());
895 WasmCompiledModule::recreate_embedded_mem_start(compiled_module, factory,
896 start_address);
897 WasmCompiledModule::recreate_embedded_mem_size(compiled_module, factory,
898 size);
899 } else {
900 compiled_module->set_embedded_mem_start(start_address);
901 compiled_module->set_embedded_mem_size(size);
902 }
903 }
904
905 void WasmCompiledModule::SetGlobalsStartAddressFrom(
906 Factory* factory, Handle<WasmCompiledModule> compiled_module,
907 Handle<JSArrayBuffer> buffer) {
908 DCHECK(!buffer.is_null());
909 size_t start_address = reinterpret_cast<size_t>(buffer->backing_store());
910 if (!compiled_module->has_globals_start()) {
911 WasmCompiledModule::recreate_globals_start(compiled_module, factory,
912 start_address);
913 } else {
914 compiled_module->set_globals_start(start_address);
915 }
916 }
917
783 MaybeHandle<String> WasmCompiledModule::ExtractUtf8StringFromModuleBytes( 918 MaybeHandle<String> WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
784 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, 919 Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
785 uint32_t offset, uint32_t size) { 920 uint32_t offset, uint32_t size) {
786 // TODO(wasm): cache strings from modules if it's a performance win. 921 // TODO(wasm): cache strings from modules if it's a performance win.
787 Handle<SeqOneByteString> module_bytes(compiled_module->module_bytes(), 922 Handle<SeqOneByteString> module_bytes(compiled_module->module_bytes(),
788 isolate); 923 isolate);
789 DCHECK_GE(module_bytes->length(), offset); 924 DCHECK_GE(module_bytes->length(), offset);
790 DCHECK_GE(module_bytes->length() - offset, size); 925 DCHECK_GE(module_bytes->length() - offset, size);
791 Address raw = module_bytes->GetCharsAddress() + offset; 926 Address raw = module_bytes->GetCharsAddress() + offset;
792 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) 927 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size))
793 return {}; // UTF8 decoding error for name. 928 return {}; // UTF8 decoding error for name.
794 DCHECK_GE(kMaxInt, offset); 929 DCHECK_GE(kMaxInt, offset);
795 DCHECK_GE(kMaxInt, size); 930 DCHECK_GE(kMaxInt, size);
796 return isolate->factory()->NewStringFromUtf8SubString( 931 return isolate->factory()->NewStringFromUtf8SubString(
797 module_bytes, static_cast<int>(offset), static_cast<int>(size)); 932 module_bytes, static_cast<int>(offset), static_cast<int>(size));
798 } 933 }
799 934
800 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { 935 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) {
801 if (!obj->IsFixedArray()) return false; 936 if (!obj->IsFixedArray()) return false;
802 FixedArray* arr = FixedArray::cast(obj); 937 FixedArray* arr = FixedArray::cast(obj);
803 if (arr->length() != PropertyIndices::Count) return false; 938 if (arr->length() != PropertyIndices::Count) return false;
804 Isolate* isolate = arr->GetIsolate(); 939 Isolate* isolate = arr->GetIsolate();
805 #define WCM_CHECK_TYPE(NAME, TYPE_CHECK) \ 940 #define WCM_CHECK_TYPE(NAME, TYPE_CHECK) \
806 do { \ 941 do { \
807 Object* obj = arr->get(kID_##NAME); \ 942 Object* obj = arr->get(kID_##NAME); \
808 if (!(TYPE_CHECK)) return false; \ 943 if (!(TYPE_CHECK)) return false; \
809 } while (false); 944 } while (false);
945 // We're OK with undefined, generally, because maybe we don't
946 // have a value for that item. For example, we may not have a
947 // memory, or globals.
948 // We're not OK with the fixed numbers being undefined. We want
949 // to set once all of them.
810 #define WCM_CHECK_OBJECT(TYPE, NAME) \ 950 #define WCM_CHECK_OBJECT(TYPE, NAME) \
811 WCM_CHECK_TYPE(NAME, obj->IsUndefined(isolate) || obj->Is##TYPE()) 951 WCM_CHECK_TYPE(NAME, obj->IsUndefined(isolate) || obj->Is##TYPE())
812 #define WCM_CHECK_WASM_OBJECT(TYPE, NAME) \ 952 #define WCM_CHECK_WASM_OBJECT(TYPE, NAME) \
813 WCM_CHECK_TYPE(NAME, TYPE::Is##TYPE(obj)) 953 WCM_CHECK_TYPE(NAME, TYPE::Is##TYPE(obj))
814 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT(WeakCell, NAME) 954 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT(WeakCell, NAME)
815 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) WCM_CHECK_TYPE(NAME, obj->IsSmi()) 955 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \
956 WCM_CHECK_TYPE(NAME, obj->IsUndefined(isolate) || obj->IsSmi())
816 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) 957 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME)
958 #define WCM_CHECK_SMALL_FIXED_NUMBER(TYPE, NAME) \
959 WCM_CHECK_TYPE(NAME, obj->IsSmi())
960 #define WCM_CHECK_LARGE_NUMBER(TYPE, NAME) \
961 WCM_CHECK_TYPE(NAME, obj->IsUndefined(isolate) || obj->IsMutableHeapNumber())
817 WCM_PROPERTY_TABLE(WCM_CHECK) 962 WCM_PROPERTY_TABLE(WCM_CHECK)
818 #undef WCM_CHECK 963 #undef WCM_CHECK
819 964
820 // All checks passed. 965 // All checks passed.
821 return true; 966 return true;
822 } 967 }
823 968
824 void WasmCompiledModule::PrintInstancesChain() { 969 void WasmCompiledModule::PrintInstancesChain() {
825 #if DEBUG 970 #if DEBUG
826 if (!FLAG_trace_wasm_instances) return; 971 if (!FLAG_trace_wasm_instances) return;
(...skipping 11 matching lines...) Expand all
838 void WasmCompiledModule::ReinitializeAfterDeserialization( 983 void WasmCompiledModule::ReinitializeAfterDeserialization(
839 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { 984 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
840 // This method must only be called immediately after deserialization. 985 // This method must only be called immediately after deserialization.
841 // At this point, no module wrapper exists, so the shared module data is 986 // At this point, no module wrapper exists, so the shared module data is
842 // incomplete. 987 // incomplete.
843 Handle<WasmSharedModuleData> shared( 988 Handle<WasmSharedModuleData> shared(
844 static_cast<WasmSharedModuleData*>(compiled_module->get(kID_shared)), 989 static_cast<WasmSharedModuleData*>(compiled_module->get(kID_shared)),
845 isolate); 990 isolate);
846 DCHECK(!WasmSharedModuleData::IsWasmSharedModuleData(*shared)); 991 DCHECK(!WasmSharedModuleData::IsWasmSharedModuleData(*shared));
847 WasmSharedModuleData::ReinitializeAfterDeserialization(isolate, shared); 992 WasmSharedModuleData::ReinitializeAfterDeserialization(isolate, shared);
993 WasmCompiledModule::Reset(isolate, *compiled_module);
848 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); 994 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared));
849 } 995 }
850 996
851 uint32_t WasmCompiledModule::mem_size() const { 997 uint32_t WasmCompiledModule::mem_size() const {
852 return has_memory() ? memory()->byte_length()->Number() : default_mem_size(); 998 DCHECK(has_embedded_mem_size() == has_embedded_mem_start());
999 return has_embedded_mem_start() ? embedded_mem_size() : default_mem_size();
853 } 1000 }
854 1001
855 uint32_t WasmCompiledModule::default_mem_size() const { 1002 uint32_t WasmCompiledModule::default_mem_size() const {
856 return min_mem_pages() * WasmModule::kPageSize; 1003 return min_mem_pages() * WasmModule::kPageSize;
857 } 1004 }
858 1005
859 MaybeHandle<String> WasmCompiledModule::GetFunctionNameOrNull( 1006 MaybeHandle<String> WasmCompiledModule::GetFunctionNameOrNull(
860 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, 1007 Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
861 uint32_t func_index) { 1008 uint32_t func_index) {
862 DCHECK_LT(func_index, compiled_module->module()->functions.size()); 1009 DCHECK_LT(func_index, compiled_module->module()->functions.size());
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 if (!array->get(kWrapperInstanceObject)->IsWeakCell()) return false; 1361 if (!array->get(kWrapperInstanceObject)->IsWeakCell()) return false;
1215 Isolate* isolate = array->GetIsolate(); 1362 Isolate* isolate = array->GetIsolate();
1216 if (!array->get(kNextInstanceWrapper)->IsUndefined(isolate) && 1363 if (!array->get(kNextInstanceWrapper)->IsUndefined(isolate) &&
1217 !array->get(kNextInstanceWrapper)->IsFixedArray()) 1364 !array->get(kNextInstanceWrapper)->IsFixedArray())
1218 return false; 1365 return false;
1219 if (!array->get(kPreviousInstanceWrapper)->IsUndefined(isolate) && 1366 if (!array->get(kPreviousInstanceWrapper)->IsUndefined(isolate) &&
1220 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) 1367 !array->get(kPreviousInstanceWrapper)->IsFixedArray())
1221 return false; 1368 return false;
1222 return true; 1369 return true;
1223 } 1370 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-objects.h ('k') | test/mjsunit/wasm/compiled-module-serialization.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698