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

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

Issue 2383623003: Revert of [wasm] Strongly typed compiled module (Closed)
Patch Set: Created 4 years, 2 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-module.h ('k') | no next file » | 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 kWasmGlobalsArrayBuffer, 147 kWasmGlobalsArrayBuffer,
148 // TODO(clemensh): Remove function name array, extract names from module 148 // TODO(clemensh): Remove function name array, extract names from module
149 // bytes. 149 // bytes.
150 kWasmFunctionNamesArray, 150 kWasmFunctionNamesArray,
151 kWasmModuleBytesString, 151 kWasmModuleBytesString,
152 kWasmDebugInfo, 152 kWasmDebugInfo,
153 kWasmNumImportedFunctions, 153 kWasmNumImportedFunctions,
154 kWasmModuleInternalFieldCount 154 kWasmModuleInternalFieldCount
155 }; 155 };
156 156
157 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code.
158 // For now, each field is expected to have the type commented by its side.
159 // The elements typed as "maybe" are optional. The others are mandatory. Since
160 // the compiled module is either obtained from the current v8 instance, or from
161 // a snapshot produced by a compatible (==identical) v8 instance, we simply
162 // fail at instantiation time, in the face of invalid data.
163 enum WasmCompiledModule {
164 kCodeTable, // FixedArray of Code
165 kImportData, // maybe FixedArray of FixedArray respecting the
166 // WasmImportData structure.
167 kExportData, // maybe FixedArray of FixedArray of WasmExportData
168 // structure
169 kStartupData, // maybe FixedArray of WasmExportData structure
170 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of
171 // WasmIndirectFunctionTableData
172 kModuleBytes, // maybe String
173 kFunctionNameTable, // maybe ByteArray
174 kMinRequiredMemory, // Smi. an uint32_t
175 // The following 2 are either together present or absent:
176 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
177 // WasmSegmentInfo structure
178 kDataSegments, // maybe ByteArray.
179
180 kGlobalsSize, // Smi. an uint32_t
181 kMemSize, // Smi.an uint32_t
182 kMemStart, // MaybeHandle<ArrayBuffer>
183 kExportMem, // Smi. bool
184 kOrigin, // Smi. ModuleOrigin
185 kNextInstance, // WeakCell. See compiled code cloning.
186 kPrevInstance, // WeakCell. See compiled code cloning.
187 kOwningInstance, // WeakCell, pointing to the owning instance.
188 kModuleObject, // WeakCell, pointing to the module object.
189 kWasmCompiledModuleSize // Sentinel value.
190 };
191
157 enum WasmImportData { 192 enum WasmImportData {
158 kModuleName, // String 193 kModuleName, // String
159 kFunctionName, // maybe String 194 kFunctionName, // maybe String
160 kOutputCount, // Smi. an uint32_t 195 kOutputCount, // Smi. an uint32_t
161 kSignature, // ByteArray. A copy of the data in FunctionSig 196 kSignature, // ByteArray. A copy of the data in FunctionSig
162 kWasmImportDataSize // Sentinel value. 197 kWasmImportDataSize // Sentinel value.
163 }; 198 };
164 199
165 enum WasmExportData { 200 enum WasmExportData {
166 kExportName, // String 201 kExportName, // String
(...skipping 12 matching lines...) Expand all
179 enum WasmIndirectFunctionTableData { 214 enum WasmIndirectFunctionTableData {
180 kSize, // Smi. an uint32_t 215 kSize, // Smi. an uint32_t
181 kTable, // FixedArray of indirect function table 216 kTable, // FixedArray of indirect function table
182 kWasmIndirectFunctionTableDataSize // Sentinel value. 217 kWasmIndirectFunctionTableDataSize // Sentinel value.
183 }; 218 };
184 219
185 uint32_t GetMinModuleMemSize(const WasmModule* module) { 220 uint32_t GetMinModuleMemSize(const WasmModule* module) {
186 return WasmModule::kPageSize * module->min_mem_pages; 221 return WasmModule::kPageSize * module->min_mem_pages;
187 } 222 }
188 223
189 void LoadDataSegments(Handle<WasmCompiledModule> compiled_module, 224 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr,
190 Address mem_addr, size_t mem_size) { 225 size_t mem_size) {
191 CHECK(compiled_module->has_data_segments() == 226 Isolate* isolate = compiled_module->GetIsolate();
192 compiled_module->has_data_segments_info()); 227 MaybeHandle<ByteArray> maybe_data =
228 compiled_module->GetValue<ByteArray>(isolate, kDataSegments);
229 MaybeHandle<FixedArray> maybe_segments =
230 compiled_module->GetValue<FixedArray>(isolate, kDataSegmentsInfo);
193 231
232 // We either have both or neither.
233 CHECK(maybe_data.is_null() == maybe_segments.is_null());
194 // If we have neither, we're done. 234 // If we have neither, we're done.
195 if (!compiled_module->has_data_segments()) return; 235 if (maybe_data.is_null()) return;
196 236
197 Handle<ByteArray> data = compiled_module->data_segments(); 237 Handle<ByteArray> data = maybe_data.ToHandleChecked();
198 Handle<FixedArray> segments = compiled_module->data_segments_info(); 238 Handle<FixedArray> segments = maybe_segments.ToHandleChecked();
199 239
200 uint32_t last_extraction_pos = 0; 240 uint32_t last_extraction_pos = 0;
201 for (int i = 0; i < segments->length(); ++i) { 241 for (int i = 0; i < segments->length(); ++i) {
202 Handle<ByteArray> segment = 242 Handle<ByteArray> segment =
203 Handle<ByteArray>(ByteArray::cast(segments->get(i))); 243 Handle<ByteArray>(ByteArray::cast(segments->get(i)));
204 uint32_t dest_addr = static_cast<uint32_t>(segment->get_int(kDestAddr)); 244 uint32_t dest_addr = static_cast<uint32_t>(segment->get_int(kDestAddr));
205 uint32_t source_size = static_cast<uint32_t>(segment->get_int(kSourceSize)); 245 uint32_t source_size = static_cast<uint32_t>(segment->get_int(kSourceSize));
206 CHECK_LT(dest_addr, mem_size); 246 CHECK_LT(dest_addr, mem_size);
207 CHECK_LE(source_size, mem_size); 247 CHECK_LE(source_size, mem_size);
208 CHECK_LE(dest_addr, mem_size - source_size); 248 CHECK_LE(dest_addr, mem_size - source_size);
209 byte* addr = mem_addr + dest_addr; 249 byte* addr = mem_addr + dest_addr;
210 data->copy_out(last_extraction_pos, addr, source_size); 250 data->copy_out(last_extraction_pos, addr, source_size);
211 last_extraction_pos += source_size; 251 last_extraction_pos += source_size;
212 } 252 }
213 } 253 }
214 254
215 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module, 255 void SaveDataSegmentInfo(Factory* factory, const WasmModule* module,
216 Handle<WasmCompiledModule> compiled_module) { 256 Handle<FixedArray> compiled_module) {
217 Handle<FixedArray> segments = factory->NewFixedArray( 257 Handle<FixedArray> segments = factory->NewFixedArray(
218 static_cast<int>(module->data_segments.size()), TENURED); 258 static_cast<int>(module->data_segments.size()), TENURED);
219 uint32_t data_size = 0; 259 uint32_t data_size = 0;
220 for (const WasmDataSegment& segment : module->data_segments) { 260 for (const WasmDataSegment& segment : module->data_segments) {
221 if (segment.source_size == 0) continue; 261 if (segment.source_size == 0) continue;
222 data_size += segment.source_size; 262 data_size += segment.source_size;
223 } 263 }
224 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED); 264 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED);
225 265
226 uint32_t last_insertion_pos = 0; 266 uint32_t last_insertion_pos = 0;
227 for (uint32_t i = 0; i < module->data_segments.size(); ++i) { 267 for (uint32_t i = 0; i < module->data_segments.size(); ++i) {
228 const WasmDataSegment& segment = module->data_segments[i]; 268 const WasmDataSegment& segment = module->data_segments[i];
229 if (segment.source_size == 0) continue; 269 if (segment.source_size == 0) continue;
230 Handle<ByteArray> js_segment = 270 Handle<ByteArray> js_segment =
231 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); 271 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED);
232 // TODO(titzer): add support for global offsets for dest_addr 272 // TODO(titzer): add support for global offsets for dest_addr
233 CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind); 273 CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind);
234 js_segment->set_int(kDestAddr, segment.dest_addr.val.i32_const); 274 js_segment->set_int(kDestAddr, segment.dest_addr.val.i32_const);
235 js_segment->set_int(kSourceSize, segment.source_size); 275 js_segment->set_int(kSourceSize, segment.source_size);
236 segments->set(i, *js_segment); 276 segments->set(i, *js_segment);
237 data->copy_in(last_insertion_pos, 277 data->copy_in(last_insertion_pos,
238 module->module_start + segment.source_offset, 278 module->module_start + segment.source_offset,
239 segment.source_size); 279 segment.source_size);
240 last_insertion_pos += segment.source_size; 280 last_insertion_pos += segment.source_size;
241 } 281 }
242 compiled_module->set_data_segments_info(segments); 282 compiled_module->set(kDataSegmentsInfo, *segments);
243 compiled_module->set_data_segments(data); 283 compiled_module->set(kDataSegments, *data);
244 } 284 }
245 285
246 void PatchFunctionTable(Handle<Code> code, 286 void PatchFunctionTable(Handle<Code> code,
247 Handle<FixedArray> old_indirect_table, 287 Handle<FixedArray> old_indirect_table,
248 Handle<FixedArray> new_indirect_table) { 288 Handle<FixedArray> new_indirect_table) {
249 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); 289 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
250 it.next()) { 290 it.next()) {
251 if (it.rinfo()->target_object() == *old_indirect_table) { 291 if (it.rinfo()->target_object() == *old_indirect_table) {
252 it.rinfo()->set_target_object(*new_indirect_table); 292 it.rinfo()->set_target_object(*new_indirect_table);
253 } 293 }
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 if (new_code != old_code) { 881 if (new_code != old_code) {
842 it.rinfo()->set_target_address(new_code->instruction_start(), 882 it.rinfo()->set_target_address(new_code->instruction_start(),
843 UPDATE_WRITE_BARRIER, 883 UPDATE_WRITE_BARRIER,
844 SKIP_ICACHE_FLUSH); 884 SKIP_ICACHE_FLUSH);
845 } 885 }
846 } 886 }
847 } 887 }
848 } 888 }
849 } 889 }
850 890
891 #define GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(Field) \
892 WeakCell* Get##Field(const FixedArray* compiled_module) { \
893 Object* obj = compiled_module->get(k##Field); \
894 DCHECK_NOT_NULL(obj); \
895 if (obj->IsWeakCell()) { \
896 return WeakCell::cast(obj); \
897 } else { \
898 return nullptr; \
899 } \
900 }
901
902 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(NextInstance)
903 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(PrevInstance)
904 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(OwningInstance)
905 GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(ModuleObject)
906
851 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, 907 static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
852 WasmCompiledModule* compiled_module) { 908 FixedArray* compiled_module) {
853 Object* undefined = *isolate->factory()->undefined_value(); 909 Object* undefined = *isolate->factory()->undefined_value();
854 uint32_t old_mem_size = compiled_module->mem_size(); 910 Object* mem_size_obj = compiled_module->get(kMemSize);
855 Object* mem_start = compiled_module->ptr_to_mem_start(); 911 DCHECK(mem_size_obj->IsMutableHeapNumber());
912 uint32_t old_mem_size =
913 static_cast<uint32_t>(HeapNumber::cast(mem_size_obj)->value());
914 Object* mem_start = compiled_module->get(kMemStart);
856 Address old_mem_address = nullptr; 915 Address old_mem_address = nullptr;
857 Address globals_start = 916 Address globals_start =
858 GetGlobalStartAddressFromCodeTemplate(undefined, owner); 917 GetGlobalStartAddressFromCodeTemplate(undefined, owner);
859 918
860 if (old_mem_size > 0) { 919 if (old_mem_size > 0) {
861 CHECK_NE(mem_start, undefined); 920 CHECK_NE(mem_start, undefined);
862 old_mem_address = 921 old_mem_address =
863 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store()); 922 static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store());
864 } 923 }
865 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) | 924 int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) |
866 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) | 925 RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) |
867 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE); 926 RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE);
868 927
869 Object* fct_obj = compiled_module->ptr_to_code_table(); 928 Object* fct_obj = compiled_module->get(kCodeTable);
870 if (fct_obj != nullptr && fct_obj != undefined && 929 if (fct_obj != nullptr && fct_obj != undefined &&
871 (old_mem_size > 0 || globals_start != nullptr)) { 930 (old_mem_size > 0 || globals_start != nullptr)) {
872 FixedArray* functions = FixedArray::cast(fct_obj); 931 FixedArray* functions = FixedArray::cast(fct_obj);
873 for (int i = 0; i < functions->length(); ++i) { 932 for (int i = 0; i < functions->length(); ++i) {
874 Code* code = Code::cast(functions->get(i)); 933 Code* code = Code::cast(functions->get(i));
875 bool changed = false; 934 bool changed = false;
876 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { 935 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
877 RelocInfo::Mode mode = it.rinfo()->rmode(); 936 RelocInfo::Mode mode = it.rinfo()->rmode();
878 if (RelocInfo::IsWasmMemoryReference(mode) || 937 if (RelocInfo::IsWasmMemoryReference(mode) ||
879 RelocInfo::IsWasmMemorySizeReference(mode)) { 938 RelocInfo::IsWasmMemorySizeReference(mode)) {
880 it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr, 939 it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr,
881 old_mem_size, old_mem_size); 940 old_mem_size, old_mem_size);
882 changed = true; 941 changed = true;
883 } else { 942 } else {
884 CHECK(RelocInfo::IsWasmGlobalReference(mode)); 943 CHECK(RelocInfo::IsWasmGlobalReference(mode));
885 it.rinfo()->update_wasm_global_reference(globals_start, nullptr); 944 it.rinfo()->update_wasm_global_reference(globals_start, nullptr);
886 changed = true; 945 changed = true;
887 } 946 }
888 } 947 }
889 if (changed) { 948 if (changed) {
890 Assembler::FlushICache(isolate, code->instruction_start(), 949 Assembler::FlushICache(isolate, code->instruction_start(),
891 code->instruction_size()); 950 code->instruction_size());
892 } 951 }
893 } 952 }
894 } 953 }
895 compiled_module->reset_weak_owning_instance(); 954 compiled_module->set(kOwningInstance, undefined);
896 compiled_module->reset_mem_start(); 955 compiled_module->set(kMemStart, undefined);
897 } 956 }
898 957
899 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { 958 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
900 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); 959 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
901 JSObject* owner = *p; 960 JSObject* owner = *p;
902 WasmCompiledModule* compiled_module = 961 FixedArray* compiled_module =
903 WasmCompiledModule::cast(owner->GetInternalField(kWasmCompiledModule)); 962 FixedArray::cast(owner->GetInternalField(kWasmCompiledModule));
904 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); 963 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
905 DCHECK(compiled_module->has_weak_module_object()); 964 Object* undefined = *isolate->factory()->undefined_value();
906 WeakCell* weak_module_obj = compiled_module->ptr_to_weak_module_object(); 965 WeakCell* weak_module_obj = GetModuleObject(compiled_module);
907 966 DCHECK_NOT_NULL(weak_module_obj);
908 // weak_module_obj may have been cleared, meaning the module object 967 // weak_module_obj may have been cleared, meaning the module object
909 // was GC-ed. In that case, there won't be any new instances created, 968 // was GC-ed. In that case, there won't be any new instances created,
910 // and we don't need to maintain the links between instances. 969 // and we don't need to maintain the links between instances.
911 if (!weak_module_obj->cleared()) { 970 if (!weak_module_obj->cleared()) {
912 JSObject* module_obj = JSObject::cast(weak_module_obj->value()); 971 JSObject* module_obj = JSObject::cast(weak_module_obj->value());
913 WasmCompiledModule* current_template = 972 FixedArray* current_template =
914 WasmCompiledModule::cast(module_obj->GetInternalField(0)); 973 FixedArray::cast(module_obj->GetInternalField(0));
915 DCHECK(!current_template->has_weak_prev_instance()); 974 DCHECK_NULL(GetPrevInstance(current_template));
916 WeakCell* next = compiled_module->ptr_to_weak_next_instance(); 975 WeakCell* next = GetNextInstance(compiled_module);
917 WeakCell* prev = compiled_module->ptr_to_weak_prev_instance(); 976 WeakCell* prev = GetPrevInstance(compiled_module);
918 977
919 if (current_template == compiled_module) { 978 if (current_template == compiled_module) {
920 if (next == nullptr) { 979 if (next == nullptr) {
921 ResetCompiledModule(isolate, owner, compiled_module); 980 ResetCompiledModule(isolate, owner, compiled_module);
922 } else { 981 } else {
923 DCHECK(next->value()->IsFixedArray()); 982 DCHECK(next->value()->IsFixedArray());
924 module_obj->SetInternalField(0, next->value()); 983 module_obj->SetInternalField(0, next->value());
925 DCHECK_NULL(prev); 984 DCHECK_NULL(prev);
926 WasmCompiledModule::cast(next->value())->reset_weak_prev_instance(); 985 FixedArray::cast(next->value())->set(kPrevInstance, undefined);
927 } 986 }
928 } else { 987 } else {
929 DCHECK(!(prev == nullptr && next == nullptr)); 988 DCHECK(!(prev == nullptr && next == nullptr));
930 // the only reason prev or next would be cleared is if the 989 // the only reason prev or next would be cleared is if the
931 // respective objects got collected, but if that happened, 990 // respective objects got collected, but if that happened,
932 // we would have relinked the list. 991 // we would have relinked the list.
933 if (prev != nullptr) { 992 if (prev != nullptr) {
934 DCHECK(!prev->cleared()); 993 DCHECK(!prev->cleared());
935 if (next == nullptr) { 994 FixedArray::cast(prev->value())
936 WasmCompiledModule::cast(prev->value())->reset_weak_next_instance(); 995 ->set(kNextInstance, next == nullptr ? undefined : next);
937 } else {
938 WasmCompiledModule::cast(prev->value())
939 ->set_ptr_to_weak_next_instance(next);
940 }
941 } 996 }
942 if (next != nullptr) { 997 if (next != nullptr) {
943 DCHECK(!next->cleared()); 998 DCHECK(!next->cleared());
944 if (prev == nullptr) { 999 FixedArray::cast(next->value())
945 WasmCompiledModule::cast(next->value())->reset_weak_prev_instance(); 1000 ->set(kPrevInstance, prev == nullptr ? undefined : prev);
946 } else {
947 WasmCompiledModule::cast(next->value())
948 ->set_ptr_to_weak_prev_instance(prev);
949 }
950 } 1001 }
951 } 1002 }
952 } 1003 }
953 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); 1004 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
954 } 1005 }
955 1006
956 } // namespace 1007 } // namespace
957 1008
958 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( 1009 MaybeHandle<FixedArray> WasmModule::CompileFunctions(
959 Isolate* isolate, ErrorThrower* thrower) const { 1010 Isolate* isolate, ErrorThrower* thrower) const {
960 Factory* factory = isolate->factory(); 1011 Factory* factory = isolate->factory();
961 1012
962 MaybeHandle<WasmCompiledModule> nothing; 1013 MaybeHandle<FixedArray> nothing;
963 1014
964 WasmModuleInstance temp_instance(this); 1015 WasmModuleInstance temp_instance(this);
965 temp_instance.context = isolate->native_context(); 1016 temp_instance.context = isolate->native_context();
966 temp_instance.mem_size = GetMinModuleMemSize(this); 1017 temp_instance.mem_size = GetMinModuleMemSize(this);
967 temp_instance.mem_start = nullptr; 1018 temp_instance.mem_start = nullptr;
968 temp_instance.globals_start = nullptr; 1019 temp_instance.globals_start = nullptr;
969 1020
970 MaybeHandle<FixedArray> indirect_table = 1021 MaybeHandle<FixedArray> indirect_table =
971 function_tables.size() 1022 function_tables.size()
972 ? factory->NewFixedArray(static_cast<int>(function_tables.size()), 1023 ? factory->NewFixedArray(static_cast<int>(function_tables.size()),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 // TODO(mtrofin): do we need to flush the cache here? 1094 // TODO(mtrofin): do we need to flush the cache here?
1044 Assembler::FlushICache(isolate, code->instruction_start(), 1095 Assembler::FlushICache(isolate, code->instruction_start(),
1045 code->instruction_size()); 1096 code->instruction_size());
1046 } 1097 }
1047 } 1098 }
1048 1099
1049 // Create the compiled module object, and populate with compiled functions 1100 // Create the compiled module object, and populate with compiled functions
1050 // and information needed at instantiation time. This object needs to be 1101 // and information needed at instantiation time. This object needs to be
1051 // serializable. Instantiation may occur off a deserialized version of this 1102 // serializable. Instantiation may occur off a deserialized version of this
1052 // object. 1103 // object.
1053 Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate); 1104 Handle<FixedArray> ret =
1054 ret->set_code_table(code_table); 1105 factory->NewFixedArray(kWasmCompiledModuleSize, TENURED);
1106 ret->set(kCodeTable, *code_table);
1055 if (!indirect_table.is_null()) { 1107 if (!indirect_table.is_null()) {
1056 ret->set_indirect_function_tables(indirect_table.ToHandleChecked()); 1108 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked());
1057 } 1109 }
1058 Handle<FixedArray> import_data = GetImportsData(factory, this); 1110 Handle<FixedArray> import_data = GetImportsData(factory, this);
1059 ret->set_import_data(import_data); 1111 ret->set(kImportData, *import_data);
1060 1112
1061 // Compile exported function wrappers. 1113 // Compile exported function wrappers.
1062 int export_size = static_cast<int>(num_exported_functions); 1114 int export_size = static_cast<int>(num_exported_functions);
1063 if (export_size > 0) { 1115 if (export_size > 0) {
1064 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1116 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1065 int index = -1; 1117 int index = -1;
1066 1118
1067 for (const WasmExport& exp : export_table) { 1119 for (const WasmExport& exp : export_table) {
1068 if (exp.kind != kExternalFunction) 1120 if (exp.kind != kExternalFunction)
1069 continue; // skip non-function exports. 1121 continue; // skip non-function exports.
(...skipping 17 matching lines...) Expand all
1087 if (thrower->error()) return nothing; 1139 if (thrower->error()) return nothing;
1088 export_data->set(kExportName, *name); 1140 export_data->set(kExportName, *name);
1089 export_data->set(kExportArity, 1141 export_data->set(kExportArity,
1090 Smi::FromInt(static_cast<int>( 1142 Smi::FromInt(static_cast<int>(
1091 functions[exp.index].sig->parameter_count()))); 1143 functions[exp.index].sig->parameter_count())));
1092 export_data->set(kExportedFunctionIndex, 1144 export_data->set(kExportedFunctionIndex,
1093 Smi::FromInt(static_cast<int>(exp.index))); 1145 Smi::FromInt(static_cast<int>(exp.index)));
1094 exports->set(index, *export_data); 1146 exports->set(index, *export_data);
1095 code_table->set(static_cast<int>(functions.size() + index), *export_code); 1147 code_table->set(static_cast<int>(functions.size() + index), *export_code);
1096 } 1148 }
1097 ret->set_exports(exports); 1149 ret->set(kExportData, *exports);
1098 } 1150 }
1099 1151
1100 // Record data for startup function. 1152 // Record data for startup function.
1101 if (start_function_index >= 0) { 1153 if (start_function_index >= 0) {
1102 HandleScope scope(isolate); 1154 HandleScope scope(isolate);
1103 Handle<FixedArray> startup_data = 1155 Handle<FixedArray> startup_data =
1104 factory->NewFixedArray(kWasmExportDataSize, TENURED); 1156 factory->NewFixedArray(kWasmExportDataSize, TENURED);
1105 startup_data->set(kExportArity, Smi::FromInt(0)); 1157 startup_data->set(kExportArity, Smi::FromInt(0));
1106 startup_data->set(kExportedFunctionIndex, 1158 startup_data->set(kExportedFunctionIndex,
1107 Smi::FromInt(start_function_index)); 1159 Smi::FromInt(start_function_index));
1108 ret->set_startup_function(startup_data); 1160 ret->set(kStartupData, *startup_data);
1109 } 1161 }
1110 1162
1111 // TODO(wasm): saving the module bytes for debugging is wasteful. We should 1163 // TODO(wasm): saving the module bytes for debugging is wasteful. We should
1112 // consider downloading this on-demand. 1164 // consider downloading this on-demand.
1113 { 1165 {
1114 size_t module_bytes_len = module_end - module_start; 1166 size_t module_bytes_len = module_end - module_start;
1115 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); 1167 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt));
1116 Vector<const uint8_t> module_bytes_vec(module_start, 1168 Vector<const uint8_t> module_bytes_vec(module_start,
1117 static_cast<int>(module_bytes_len)); 1169 static_cast<int>(module_bytes_len));
1118 Handle<String> module_bytes_string = 1170 Handle<String> module_bytes_string =
1119 factory->NewStringFromOneByte(module_bytes_vec, TENURED) 1171 factory->NewStringFromOneByte(module_bytes_vec, TENURED)
1120 .ToHandleChecked(); 1172 .ToHandleChecked();
1121 ret->set_module_bytes(module_bytes_string); 1173 ret->set(kModuleBytes, *module_bytes_string);
1122 } 1174 }
1123 1175
1124 Handle<ByteArray> function_name_table = 1176 Handle<ByteArray> function_name_table =
1125 BuildFunctionNamesTable(isolate, module_env.module); 1177 BuildFunctionNamesTable(isolate, module_env.module);
1126 ret->set_function_names(function_name_table); 1178 ret->set(kFunctionNameTable, *function_name_table);
1127 ret->set_min_required_memory(min_mem_pages); 1179 ret->set(kMinRequiredMemory, Smi::FromInt(min_mem_pages));
1128 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); 1180 if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
1129 ret->set_globals_size(globals_size); 1181 ret->set(kGlobalsSize, Smi::FromInt(globals_size));
1130 ret->set_export_memory(mem_export); 1182 ret->set(kExportMem, Smi::FromInt(mem_export));
1131 ret->set_origin(origin); 1183 ret->set(kOrigin, Smi::FromInt(origin));
1132 ret->set_mem_size(temp_instance.mem_size); 1184 Handle<HeapNumber> size_as_object = factory->NewHeapNumber(
1185 static_cast<double>(temp_instance.mem_size), MUTABLE, TENURED);
1186 ret->set(kMemSize, *size_as_object);
1133 return ret; 1187 return ret;
1134 } 1188 }
1135 1189
1136 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper, 1190 void PatchJSWrapper(Isolate* isolate, Handle<Code> wrapper,
1137 Handle<Code> new_target) { 1191 Handle<Code> new_target) {
1138 AllowDeferredHandleDereference embedding_raw_address; 1192 AllowDeferredHandleDereference embedding_raw_address;
1139 bool seen = false; 1193 bool seen = false;
1140 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done(); 1194 for (RelocIterator it(*wrapper, 1 << RelocInfo::CODE_TARGET); !it.done();
1141 it.next()) { 1195 it.next()) {
1142 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 1196 Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 Handle<JSReceiver> ffi, 1244 Handle<JSReceiver> ffi,
1191 Handle<JSArrayBuffer> memory) { 1245 Handle<JSArrayBuffer> memory) {
1192 MaybeHandle<JSObject> nothing; 1246 MaybeHandle<JSObject> nothing;
1193 HistogramTimerScope wasm_instantiate_module_time_scope( 1247 HistogramTimerScope wasm_instantiate_module_time_scope(
1194 isolate->counters()->wasm_instantiate_module_time()); 1248 isolate->counters()->wasm_instantiate_module_time());
1195 Factory* factory = isolate->factory(); 1249 Factory* factory = isolate->factory();
1196 1250
1197 //-------------------------------------------------------------------------- 1251 //--------------------------------------------------------------------------
1198 // Reuse the compiled module (if no owner), otherwise clone. 1252 // Reuse the compiled module (if no owner), otherwise clone.
1199 //-------------------------------------------------------------------------- 1253 //--------------------------------------------------------------------------
1200 Handle<WasmCompiledModule> compiled_module; 1254 Handle<FixedArray> compiled_module;
1201 Handle<FixedArray> code_table; 1255 Handle<FixedArray> code_table;
1202 Handle<FixedArray> old_code_table; 1256 Handle<FixedArray> old_code_table;
1203 Handle<JSObject> owner; 1257 Handle<JSObject> owner;
1204 // If we don't clone, this will be null(). Otherwise, this will 1258 // If we don't clone, this will be null(). Otherwise, this will
1205 // be a weak link to the original. If we lose the original to GC, 1259 // be a weak link to the original. If we lose the original to GC,
1206 // this will be a cleared. We'll link the instances chain last. 1260 // this will be a cleared. We'll link the instances chain last.
1207 MaybeHandle<WeakCell> link_to_original; 1261 MaybeHandle<WeakCell> link_to_original;
1208 1262
1209 { 1263 {
1210 Handle<WasmCompiledModule> original( 1264 Handle<FixedArray> original(
1211 WasmCompiledModule::cast(module_object->GetInternalField(0)), isolate); 1265 FixedArray::cast(module_object->GetInternalField(0)), isolate);
1212 // Always make a new copy of the code_table, since the old_code_table 1266 // Always make a new copy of the code_table, since the old_code_table
1213 // may still have placeholders for imports. 1267 // may still have placeholders for imports.
1214 old_code_table = original->code_table(); 1268 old_code_table = original->GetValueChecked<FixedArray>(isolate, kCodeTable);
1215 code_table = factory->CopyFixedArray(old_code_table); 1269 code_table = factory->CopyFixedArray(old_code_table);
1216 1270
1217 if (original->has_weak_owning_instance()) { 1271 WeakCell* tmp = GetOwningInstance(*original);
1218 WeakCell* tmp = original->ptr_to_weak_owning_instance(); 1272 if (tmp != nullptr) {
1219 DCHECK(!tmp->cleared()); 1273 DCHECK(!tmp->cleared());
1220 // There is already an owner, clone everything. 1274 // There is already an owner, clone everything.
1221 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate); 1275 owner = Handle<JSObject>(JSObject::cast(tmp->value()), isolate);
1222 // Insert the latest clone in front. 1276 // Insert the latest clone in front.
1223 compiled_module = 1277 compiled_module = factory->CopyFixedArray(original);
1224 handle(WasmCompiledModule::cast(*factory->CopyFixedArray(original)));
1225 // Replace the strong reference to point to the new instance here. 1278 // Replace the strong reference to point to the new instance here.
1226 // This allows any of the other instances, including the original, 1279 // This allows any of the other instances, including the original,
1227 // to be collected. 1280 // to be collected.
1228 module_object->SetInternalField(0, *compiled_module); 1281 module_object->SetInternalField(0, *compiled_module);
1229 compiled_module->set_weak_module_object(original->weak_module_object()); 1282 Handle<WeakCell> weak_link_to_wasm_obj =
1283 original->GetValueChecked<WeakCell>(isolate, kModuleObject);
1284
1285 compiled_module->set(kModuleObject, *weak_link_to_wasm_obj);
1230 link_to_original = factory->NewWeakCell(original); 1286 link_to_original = factory->NewWeakCell(original);
1231 // Don't link to original here. We remember the original 1287 // Don't link to original here. We remember the original
1232 // as a weak link. If that link isn't clear by the time we finish 1288 // as a weak link. If that link isn't clear by the time we finish
1233 // instantiating this instance, then we link it at that time. 1289 // instantiating this instance, then we link it at that time.
1234 compiled_module->reset_weak_next_instance(); 1290 compiled_module->set(kNextInstance, *factory->undefined_value());
1235 1291
1236 // Clone the code for WASM functions and exports. 1292 // Clone the code for WASM functions and exports.
1237 for (int i = 0; i < code_table->length(); ++i) { 1293 for (int i = 0; i < code_table->length(); ++i) {
1238 Handle<Code> orig_code = code_table->GetValueChecked<Code>(isolate, i); 1294 Handle<Code> orig_code = code_table->GetValueChecked<Code>(isolate, i);
1239 switch (orig_code->kind()) { 1295 switch (orig_code->kind()) {
1240 case Code::WASM_TO_JS_FUNCTION: 1296 case Code::WASM_TO_JS_FUNCTION:
1241 // Imports will be overwritten with newly compiled wrappers. 1297 // Imports will be overwritten with newly compiled wrappers.
1242 break; 1298 break;
1243 case Code::JS_TO_WASM_FUNCTION: 1299 case Code::JS_TO_WASM_FUNCTION:
1244 case Code::WASM_FUNCTION: { 1300 case Code::WASM_FUNCTION: {
1245 Handle<Code> code = factory->CopyCode(orig_code); 1301 Handle<Code> code = factory->CopyCode(orig_code);
1246 code_table->set(i, *code); 1302 code_table->set(i, *code);
1247 break; 1303 break;
1248 } 1304 }
1249 default: 1305 default:
1250 UNREACHABLE(); 1306 UNREACHABLE();
1251 } 1307 }
1252 } 1308 }
1253 compiled_module->set_mem_size(original->mem_size()); 1309 Handle<HeapNumber> size_as_object = factory->NewHeapNumber(
1310 static_cast<double>(
1311 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
1312 ->value()),
1313 MUTABLE, TENURED);
1314 compiled_module->set(kMemSize, *size_as_object);
1254 RecordStats(isolate, code_table); 1315 RecordStats(isolate, code_table);
1255 } else { 1316 } else {
1256 // There was no owner, so we can reuse the original. 1317 // There was no owner, so we can reuse the original.
1257 compiled_module = original; 1318 compiled_module = original;
1258 } 1319 }
1259 compiled_module->set_code_table(code_table); 1320 compiled_module->set(kCodeTable, *code_table);
1260 } 1321 }
1261 1322
1262 //-------------------------------------------------------------------------- 1323 //--------------------------------------------------------------------------
1263 // Allocate the instance object. 1324 // Allocate the instance object.
1264 //-------------------------------------------------------------------------- 1325 //--------------------------------------------------------------------------
1265 Handle<Map> map = factory->NewMap( 1326 Handle<Map> map = factory->NewMap(
1266 JS_OBJECT_TYPE, 1327 JS_OBJECT_TYPE,
1267 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1328 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1268 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED); 1329 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED);
1269 instance->SetInternalField(kWasmModuleCodeTable, *code_table); 1330 instance->SetInternalField(kWasmModuleCodeTable, *code_table);
1270 1331
1271 //-------------------------------------------------------------------------- 1332 //--------------------------------------------------------------------------
1272 // Set up the memory for the new instance. 1333 // Set up the memory for the new instance.
1273 //-------------------------------------------------------------------------- 1334 //--------------------------------------------------------------------------
1274 MaybeHandle<JSArrayBuffer> old_memory; 1335 MaybeHandle<JSArrayBuffer> old_memory;
1275 // TODO(titzer): handle imported memory properly. 1336 // TODO(titzer): handle imported memory properly.
1276 1337
1277 uint32_t min_mem_pages = compiled_module->min_required_memory(); 1338 uint32_t min_mem_pages = static_cast<uint32_t>(
1339 Smi::cast(compiled_module->get(kMinRequiredMemory))->value());
1278 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); 1340 isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
1279 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. 1341 // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
1280 1342
1281 if (memory.is_null() && min_mem_pages > 0) { 1343 if (memory.is_null() && min_mem_pages > 0) {
1282 memory = AllocateMemory(thrower, isolate, min_mem_pages); 1344 memory = AllocateMemory(thrower, isolate, min_mem_pages);
1283 if (memory.is_null()) return nothing; // failed to allocate memory 1345 if (memory.is_null()) return nothing; // failed to allocate memory
1284 } 1346 }
1285 1347
1286 if (!memory.is_null()) { 1348 if (!memory.is_null()) {
1287 instance->SetInternalField(kWasmMemArrayBuffer, *memory); 1349 instance->SetInternalField(kWasmMemArrayBuffer, *memory);
1288 Address mem_start = static_cast<Address>(memory->backing_store()); 1350 Address mem_start = static_cast<Address>(memory->backing_store());
1289 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); 1351 uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number());
1290 LoadDataSegments(compiled_module, mem_start, mem_size); 1352 LoadDataSegments(compiled_module, mem_start, mem_size);
1291 1353
1292 uint32_t old_mem_size = compiled_module->mem_size(); 1354 uint32_t old_mem_size = static_cast<uint32_t>(
1355 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
1356 ->value());
1357 MaybeHandle<JSArrayBuffer> old_mem =
1358 compiled_module->GetValue<JSArrayBuffer>(isolate, kMemStart);
1293 Address old_mem_start = 1359 Address old_mem_start =
1294 compiled_module->has_mem_start() 1360 old_mem.is_null()
1295 ? static_cast<Address>( 1361 ? nullptr
1296 compiled_module->mem_start()->backing_store()) 1362 : static_cast<Address>(old_mem.ToHandleChecked()->backing_store());
1297 : nullptr;
1298 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, 1363 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
1299 mem_size); 1364 mem_size);
1300 compiled_module->set_mem_size(mem_size); 1365 compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
1301 compiled_module->set_mem_start(memory); 1366 ->set_value(static_cast<double>(mem_size));
1367 compiled_module->set(kMemStart, *memory);
1302 } 1368 }
1303 1369
1304 //-------------------------------------------------------------------------- 1370 //--------------------------------------------------------------------------
1305 // Set up the globals for the new instance. 1371 // Set up the globals for the new instance.
1306 //-------------------------------------------------------------------------- 1372 //--------------------------------------------------------------------------
1307 MaybeHandle<JSArrayBuffer> old_globals; 1373 MaybeHandle<JSArrayBuffer> old_globals;
1308 MaybeHandle<JSArrayBuffer> globals; 1374 MaybeHandle<JSArrayBuffer> globals;
1309 uint32_t globals_size = compiled_module->globals_size(); 1375 uint32_t globals_size = static_cast<uint32_t>(
1376 Smi::cast(compiled_module->get(kGlobalsSize))->value());
1310 if (globals_size > 0) { 1377 if (globals_size > 0) {
1311 Handle<JSArrayBuffer> global_buffer = NewArrayBuffer(isolate, globals_size); 1378 Handle<JSArrayBuffer> global_buffer = NewArrayBuffer(isolate, globals_size);
1312 globals = global_buffer; 1379 globals = global_buffer;
1313 if (globals.is_null()) { 1380 if (globals.is_null()) {
1314 thrower->Error("Out of memory: wasm globals"); 1381 thrower->Error("Out of memory: wasm globals");
1315 return nothing; 1382 return nothing;
1316 } 1383 }
1317 Address old_address = 1384 Address old_address =
1318 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate( 1385 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1319 *isolate->factory()->undefined_value(), 1386 *isolate->factory()->undefined_value(),
1320 JSObject::cast(*owner)); 1387 JSObject::cast(*owner));
1321 RelocateGlobals(instance, old_address, 1388 RelocateGlobals(instance, old_address,
1322 static_cast<Address>(global_buffer->backing_store())); 1389 static_cast<Address>(global_buffer->backing_store()));
1323 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); 1390 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer);
1324 } 1391 }
1325 1392
1326 //-------------------------------------------------------------------------- 1393 //--------------------------------------------------------------------------
1327 // Compile the import wrappers for the new instance. 1394 // Compile the import wrappers for the new instance.
1328 //-------------------------------------------------------------------------- 1395 //--------------------------------------------------------------------------
1329 // TODO(titzer): handle imported globals and function tables. 1396 // TODO(titzer): handle imported globals and function tables.
1397 Handle<FixedArray> import_data;
1330 int num_imported_functions = 0; 1398 int num_imported_functions = 0;
1331 if (compiled_module->has_import_data()) { 1399 if (compiled_module->GetValue<FixedArray>(isolate, kImportData)
1332 Handle<FixedArray> import_data = compiled_module->import_data(); 1400 .ToHandle(&import_data)) {
1333 num_imported_functions = import_data->length(); 1401 num_imported_functions = import_data->length();
1334 for (int index = 0; index < num_imported_functions; index++) { 1402 for (int index = 0; index < num_imported_functions; index++) {
1335 Handle<Code> import_wrapper = 1403 Handle<Code> import_wrapper =
1336 CompileImportWrapper(isolate, ffi, index, import_data, thrower); 1404 CompileImportWrapper(isolate, ffi, index, import_data, thrower);
1337 if (thrower->error()) return nothing; 1405 if (thrower->error()) return nothing;
1338 code_table->set(index, *import_wrapper); 1406 code_table->set(index, *import_wrapper);
1339 RecordStats(isolate, *import_wrapper); 1407 RecordStats(isolate, *import_wrapper);
1340 } 1408 }
1341 } 1409 }
1342 1410
1343 //-------------------------------------------------------------------------- 1411 //--------------------------------------------------------------------------
1344 // Set up the debug support for the new instance. 1412 // Set up the debug support for the new instance.
1345 //-------------------------------------------------------------------------- 1413 //--------------------------------------------------------------------------
1346 // TODO(wasm): avoid referencing this stuff from the instance, use it off 1414 MaybeHandle<String> module_bytes_string =
1347 // the compiled module instead. See the following 3 assignments: 1415 compiled_module->GetValue<String>(isolate, kModuleBytes);
1348 if (compiled_module->has_module_bytes()) { 1416 if (!module_bytes_string.is_null()) {
1349 instance->SetInternalField(kWasmModuleBytesString, 1417 instance->SetInternalField(kWasmModuleBytesString,
1350 compiled_module->ptr_to_module_bytes()); 1418 *module_bytes_string.ToHandleChecked());
1351 } 1419 }
1352 1420
1353 if (compiled_module->has_function_names()) { 1421 MaybeHandle<ByteArray> function_name_table =
1354 instance->SetInternalField(kWasmFunctionNamesArray, 1422 compiled_module->GetValue<ByteArray>(isolate, kFunctionNameTable);
1355 compiled_module->ptr_to_function_names()); 1423 if (!function_name_table.is_null()) {
1424 Handle<ByteArray> handle = function_name_table.ToHandleChecked();
1425 instance->SetInternalField(kWasmFunctionNamesArray, *handle);
1356 } 1426 }
1357 1427
1358 { 1428 {
1359 Handle<Object> handle = factory->NewNumber(num_imported_functions); 1429 Handle<Object> handle = factory->NewNumber(num_imported_functions);
1360 instance->SetInternalField(kWasmNumImportedFunctions, *handle); 1430 instance->SetInternalField(kWasmNumImportedFunctions, *handle);
1361 } 1431 }
1362 1432
1363 //-------------------------------------------------------------------------- 1433 //--------------------------------------------------------------------------
1364 // Set up the runtime support for the new instance. 1434 // Set up the runtime support for the new instance.
1365 //-------------------------------------------------------------------------- 1435 //--------------------------------------------------------------------------
(...skipping 15 matching lines...) Expand all
1381 //-------------------------------------------------------------------------- 1451 //--------------------------------------------------------------------------
1382 // Set up the indirect function tables for the new instance. 1452 // Set up the indirect function tables for the new instance.
1383 //-------------------------------------------------------------------------- 1453 //--------------------------------------------------------------------------
1384 { 1454 {
1385 std::vector<Handle<Code>> functions( 1455 std::vector<Handle<Code>> functions(
1386 static_cast<size_t>(code_table->length())); 1456 static_cast<size_t>(code_table->length()));
1387 for (int i = 0; i < code_table->length(); ++i) { 1457 for (int i = 0; i < code_table->length(); ++i) {
1388 functions[i] = code_table->GetValueChecked<Code>(isolate, i); 1458 functions[i] = code_table->GetValueChecked<Code>(isolate, i);
1389 } 1459 }
1390 1460
1391 if (compiled_module->has_indirect_function_tables()) { 1461 MaybeHandle<FixedArray> maybe_indirect_tables =
1392 Handle<FixedArray> indirect_tables_template = 1462 compiled_module->GetValue<FixedArray>(isolate,
1393 compiled_module->indirect_function_tables(); 1463 kTableOfIndirectFunctionTables);
1464 Handle<FixedArray> indirect_tables_template;
1465 if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
1394 Handle<FixedArray> to_replace = 1466 Handle<FixedArray> to_replace =
1395 owner.is_null() ? indirect_tables_template 1467 owner.is_null() ? indirect_tables_template
1396 : handle(FixedArray::cast(owner->GetInternalField( 1468 : handle(FixedArray::cast(owner->GetInternalField(
1397 kWasmModuleFunctionTable))); 1469 kWasmModuleFunctionTable)));
1398 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable( 1470 Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
1399 isolate, code_table, indirect_tables_template, to_replace); 1471 isolate, code_table, indirect_tables_template, to_replace);
1400 for (int i = 0; i < indirect_tables->length(); ++i) { 1472 for (int i = 0; i < indirect_tables->length(); ++i) {
1401 Handle<FixedArray> metadata = 1473 Handle<FixedArray> metadata =
1402 indirect_tables->GetValueChecked<FixedArray>(isolate, i); 1474 indirect_tables->GetValueChecked<FixedArray>(isolate, i);
1403 uint32_t size = Smi::cast(metadata->get(kSize))->value(); 1475 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1404 Handle<FixedArray> table = 1476 Handle<FixedArray> table =
1405 metadata->GetValueChecked<FixedArray>(isolate, kTable); 1477 metadata->GetValueChecked<FixedArray>(isolate, kTable);
1406 wasm::PopulateFunctionTable(table, size, &functions); 1478 wasm::PopulateFunctionTable(table, size, &functions);
1407 } 1479 }
1408 instance->SetInternalField(kWasmModuleFunctionTable, *indirect_tables); 1480 instance->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
1409 } 1481 }
1410 } 1482 }
1411 1483
1412 //-------------------------------------------------------------------------- 1484 //--------------------------------------------------------------------------
1413 // Set up the exports object for the new instance. 1485 // Set up the exports object for the new instance.
1414 //-------------------------------------------------------------------------- 1486 //--------------------------------------------------------------------------
1415 bool mem_export = compiled_module->export_memory(); 1487 bool mem_export =
1416 ModuleOrigin origin = compiled_module->origin(); 1488 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value());
1489 ModuleOrigin origin = static_cast<ModuleOrigin>(
1490 Smi::cast(compiled_module->get(kOrigin))->value());
1417 1491
1418 if (compiled_module->has_exports() || mem_export) { 1492 MaybeHandle<FixedArray> maybe_exports =
1493 compiled_module->GetValue<FixedArray>(isolate, kExportData);
1494 if (!maybe_exports.is_null() || mem_export) {
1419 PropertyDescriptor desc; 1495 PropertyDescriptor desc;
1420 desc.set_writable(false); 1496 desc.set_writable(false);
1421 1497
1422 Handle<JSObject> exports_object = instance; 1498 Handle<JSObject> exports_object = instance;
1423 if (origin == kWasmOrigin) { 1499 if (origin == kWasmOrigin) {
1424 // Create the "exports" object. 1500 // Create the "exports" object.
1425 Handle<JSFunction> object_function = Handle<JSFunction>( 1501 Handle<JSFunction> object_function = Handle<JSFunction>(
1426 isolate->native_context()->object_function(), isolate); 1502 isolate->native_context()->object_function(), isolate);
1427 exports_object = factory->NewJSObject(object_function, TENURED); 1503 exports_object = factory->NewJSObject(object_function, TENURED);
1428 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); 1504 Handle<String> exports_name = factory->InternalizeUtf8String("exports");
1429 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY); 1505 JSObject::AddProperty(instance, exports_name, exports_object, READ_ONLY);
1430 } 1506 }
1507 Handle<FixedArray> exports;
1431 int first_export = -1; 1508 int first_export = -1;
1432 // TODO(wasm): another iteration over the code objects. 1509 // TODO(wasm): another iteration over the code objects.
1433 for (int i = 0; i < code_table->length(); i++) { 1510 for (int i = 0; i < code_table->length(); i++) {
1434 Handle<Code> code = code_table->GetValueChecked<Code>(isolate, i); 1511 Handle<Code> code = code_table->GetValueChecked<Code>(isolate, i);
1435 if (code->kind() == Code::JS_TO_WASM_FUNCTION) { 1512 if (code->kind() == Code::JS_TO_WASM_FUNCTION) {
1436 first_export = i; 1513 first_export = i;
1437 break; 1514 break;
1438 } 1515 }
1439 } 1516 }
1440 if (compiled_module->has_exports()) { 1517 if (maybe_exports.ToHandle(&exports)) {
1441 Handle<FixedArray> exports = compiled_module->exports();
1442 int export_size = exports->length(); 1518 int export_size = exports->length();
1443 for (int i = 0; i < export_size; ++i) { 1519 for (int i = 0; i < export_size; ++i) {
1444 Handle<FixedArray> export_data = 1520 Handle<FixedArray> export_data =
1445 exports->GetValueChecked<FixedArray>(isolate, i); 1521 exports->GetValueChecked<FixedArray>(isolate, i);
1446 Handle<String> name = 1522 Handle<String> name =
1447 export_data->GetValueChecked<String>(isolate, kExportName); 1523 export_data->GetValueChecked<String>(isolate, kExportName);
1448 int arity = Smi::cast(export_data->get(kExportArity))->value(); 1524 int arity = Smi::cast(export_data->get(kExportArity))->value();
1449 MaybeHandle<ByteArray> signature = 1525 MaybeHandle<ByteArray> signature =
1450 export_data->GetValue<ByteArray>(isolate, kExportedSignature); 1526 export_data->GetValue<ByteArray>(isolate, kExportedSignature);
1451 Handle<Code> export_code = 1527 Handle<Code> export_code =
(...skipping 25 matching lines...) Expand all
1477 if (num_imported_functions > 0 || !owner.is_null()) { 1553 if (num_imported_functions > 0 || !owner.is_null()) {
1478 // If the code was cloned, or new imports were compiled, patch. 1554 // If the code was cloned, or new imports were compiled, patch.
1479 PatchDirectCalls(old_code_table, code_table, num_imported_functions); 1555 PatchDirectCalls(old_code_table, code_table, num_imported_functions);
1480 } 1556 }
1481 1557
1482 FlushICache(isolate, code_table); 1558 FlushICache(isolate, code_table);
1483 1559
1484 //-------------------------------------------------------------------------- 1560 //--------------------------------------------------------------------------
1485 // Run the start function if one was specified. 1561 // Run the start function if one was specified.
1486 //-------------------------------------------------------------------------- 1562 //--------------------------------------------------------------------------
1487 if (compiled_module->has_startup_function()) { 1563 Handle<FixedArray> startup_data;
1488 Handle<FixedArray> startup_data = compiled_module->startup_function(); 1564 if (compiled_module->GetValue<FixedArray>(isolate, kStartupData)
1565 .ToHandle(&startup_data)) {
1489 HandleScope scope(isolate); 1566 HandleScope scope(isolate);
1490 int32_t start_index = 1567 int32_t start_index =
1491 startup_data->GetValueChecked<Smi>(isolate, kExportedFunctionIndex) 1568 startup_data->GetValueChecked<Smi>(isolate, kExportedFunctionIndex)
1492 ->value(); 1569 ->value();
1493 Handle<Code> startup_code = 1570 Handle<Code> startup_code =
1494 code_table->GetValueChecked<Code>(isolate, start_index); 1571 code_table->GetValueChecked<Code>(isolate, start_index);
1495 int arity = Smi::cast(startup_data->get(kExportArity))->value(); 1572 int arity = Smi::cast(startup_data->get(kExportArity))->value();
1496 MaybeHandle<ByteArray> startup_signature = 1573 MaybeHandle<ByteArray> startup_signature =
1497 startup_data->GetValue<ByteArray>(isolate, kExportedSignature); 1574 startup_data->GetValue<ByteArray>(isolate, kExportedSignature);
1498 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1575 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1499 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1576 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1500 startup_signature, instance); 1577 startup_signature, instance);
1501 RecordStats(isolate, *startup_code); 1578 RecordStats(isolate, *startup_code);
1502 // Call the JS function. 1579 // Call the JS function.
1503 Handle<Object> undefined = isolate->factory()->undefined_value(); 1580 Handle<Object> undefined = isolate->factory()->undefined_value();
1504 MaybeHandle<Object> retval = 1581 MaybeHandle<Object> retval =
1505 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1582 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1506 1583
1507 if (retval.is_null()) { 1584 if (retval.is_null()) {
1508 thrower->Error("WASM.instantiateModule(): start function failed"); 1585 thrower->Error("WASM.instantiateModule(): start function failed");
1509 return nothing; 1586 return nothing;
1510 } 1587 }
1511 } 1588 }
1512 1589
1513 DCHECK(wasm::IsWasmObject(*instance)); 1590 DCHECK(wasm::IsWasmObject(*instance));
1514 1591
1515 if (compiled_module->has_weak_module_object()) { 1592 if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) {
1516 instance->SetInternalField(kWasmCompiledModule, *compiled_module); 1593 instance->SetInternalField(kWasmCompiledModule, *compiled_module);
1517 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); 1594 Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance);
1518 1595
1519 Handle<Object> global_handle = isolate->global_handles()->Create(*instance); 1596 Handle<Object> global_handle = isolate->global_handles()->Create(*instance);
1520 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module); 1597 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module);
1521 { 1598 {
1522 DisallowHeapAllocation no_gc; 1599 DisallowHeapAllocation no_gc;
1523 compiled_module->set_weak_owning_instance(link_to_owner); 1600 compiled_module->set(kOwningInstance, *link_to_owner);
1524 Handle<WeakCell> next; 1601 Handle<WeakCell> next;
1525 if (link_to_original.ToHandle(&next) && !next->cleared()) { 1602 if (link_to_original.ToHandle(&next) && !next->cleared()) {
1526 WasmCompiledModule* original = WasmCompiledModule::cast(next->value()); 1603 FixedArray* original = FixedArray::cast(next->value());
1527 DCHECK(original->has_weak_owning_instance()); 1604 DCHECK_NOT_NULL(GetOwningInstance(original));
1528 DCHECK(!original->weak_owning_instance()->cleared()); 1605 DCHECK(!GetOwningInstance(original)->cleared());
1529 compiled_module->set_weak_next_instance(next); 1606 compiled_module->set(kNextInstance, *next);
1530 original->set_weak_prev_instance(link_to_clone); 1607 original->set(kPrevInstance, *link_to_clone);
1531 } 1608 }
1532 GlobalHandles::MakeWeak(global_handle.location(), 1609 GlobalHandles::MakeWeak(global_handle.location(),
1533 global_handle.location(), &InstanceFinalizer, 1610 global_handle.location(), &InstanceFinalizer,
1534 v8::WeakCallbackType::kFinalizer); 1611 v8::WeakCallbackType::kFinalizer);
1535 } 1612 }
1536 } 1613 }
1537 1614
1538 return instance; 1615 return instance;
1539 } 1616 }
1540 1617
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 Handle<Map> map = isolate->factory()->NewMap( 1780 Handle<Map> map = isolate->factory()->NewMap(
1704 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); 1781 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
1705 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED); 1782 module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
1706 } 1783 }
1707 module_obj->SetInternalField(0, *compiled_module); 1784 module_obj->SetInternalField(0, *compiled_module);
1708 if (origin == ModuleOrigin::kWasmOrigin) { 1785 if (origin == ModuleOrigin::kWasmOrigin) {
1709 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); 1786 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
1710 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check(); 1787 Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
1711 } 1788 }
1712 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj); 1789 Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj);
1713 WasmCompiledModule::cast(*compiled_module) 1790 compiled_module->set(kModuleObject, *link_to_module);
1714 ->set_weak_module_object(link_to_module);
1715 return module_obj; 1791 return module_obj;
1716 } 1792 }
1717 1793
1718 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate, 1794 MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
1719 const byte* start, 1795 const byte* start,
1720 const byte* end, 1796 const byte* end,
1721 ErrorThrower* thrower, 1797 ErrorThrower* thrower,
1722 ModuleOrigin origin) { 1798 ModuleOrigin origin) {
1723 MaybeHandle<JSObject> nothing; 1799 MaybeHandle<JSObject> nothing;
1724 Zone zone(isolate->allocator()); 1800 Zone zone(isolate->allocator());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>(); 1833 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>();
1758 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem)); 1834 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem));
1759 } 1835 }
1760 1836
1761 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { 1837 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
1762 DisallowHeapAllocation no_gc; 1838 DisallowHeapAllocation no_gc;
1763 DCHECK(IsWasmObject(*instance)); 1839 DCHECK(IsWasmObject(*instance));
1764 instance->SetInternalField(kWasmMemArrayBuffer, buffer); 1840 instance->SetInternalField(kWasmMemArrayBuffer, buffer);
1765 Object* module = instance->GetInternalField(kWasmCompiledModule); 1841 Object* module = instance->GetInternalField(kWasmCompiledModule);
1766 if (module->IsFixedArray()) { 1842 if (module->IsFixedArray()) {
1767 WasmCompiledModule::cast(module)->set_mem_size( 1843 HeapNumber::cast(FixedArray::cast(module)->get(kMemSize))
1768 buffer->byte_length()->Number()); 1844 ->set_value(buffer->byte_length()->Number());
1769 } 1845 }
1770 } 1846 }
1771 1847
1772 namespace testing { 1848 namespace testing {
1773 1849
1774 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj, 1850 void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
1775 int instance_count) { 1851 int instance_count) {
1776 CHECK_GE(instance_count, 0); 1852 CHECK_GE(instance_count, 0);
1777 DisallowHeapAllocation no_gc; 1853 DisallowHeapAllocation no_gc;
1778 WasmCompiledModule* compiled_module = 1854 FixedArray* compiled_module =
1779 WasmCompiledModule::cast(module_obj->GetInternalField(0)); 1855 FixedArray::cast(module_obj->GetInternalField(0));
1780 CHECK_EQ( 1856 CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()),
1781 JSObject::cast(compiled_module->ptr_to_weak_module_object()->value()), 1857 *module_obj);
1782 *module_obj);
1783 Object* prev = nullptr; 1858 Object* prev = nullptr;
1784 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; 1859 int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1;
1785 WasmCompiledModule* current_instance = compiled_module; 1860 FixedArray* current_instance = compiled_module;
1786 while (current_instance->has_weak_next_instance()) { 1861 while (GetNextInstance(current_instance) != nullptr) {
1787 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) || 1862 CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) ||
1788 current_instance->ptr_to_weak_prev_instance()->value() == prev); 1863 GetPrevInstance(current_instance)->value() == prev);
1789 CHECK_EQ(current_instance->ptr_to_weak_module_object()->value(), 1864 CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj);
1790 *module_obj); 1865 CHECK(IsWasmObject(GetOwningInstance(current_instance)->value()));
1791 CHECK(
1792 IsWasmObject(current_instance->ptr_to_weak_owning_instance()->value()));
1793 prev = current_instance; 1866 prev = current_instance;
1794 current_instance = WasmCompiledModule::cast( 1867 current_instance =
1795 current_instance->ptr_to_weak_next_instance()->value()); 1868 FixedArray::cast(GetNextInstance(current_instance)->value());
1796 ++found_instances; 1869 ++found_instances;
1797 CHECK_LE(found_instances, instance_count); 1870 CHECK_LE(found_instances, instance_count);
1798 } 1871 }
1799 CHECK_EQ(found_instances, instance_count); 1872 CHECK_EQ(found_instances, instance_count);
1800 } 1873 }
1801 1874
1802 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) { 1875 void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) {
1803 DisallowHeapAllocation no_gc; 1876 DisallowHeapAllocation no_gc;
1804 WasmCompiledModule* compiled_module = 1877 FixedArray* compiled_module =
1805 WasmCompiledModule::cast(module_obj->GetInternalField(0)); 1878 FixedArray::cast(module_obj->GetInternalField(0));
1806 CHECK(compiled_module->has_weak_module_object()); 1879 CHECK_NOT_NULL(GetModuleObject(compiled_module));
1807 CHECK_EQ(compiled_module->ptr_to_weak_module_object()->value(), *module_obj); 1880 CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj);
1808 CHECK(!compiled_module->has_weak_prev_instance()); 1881 CHECK_NULL(GetPrevInstance(compiled_module));
1809 CHECK(!compiled_module->has_weak_next_instance()); 1882 CHECK_NULL(GetNextInstance(compiled_module));
1810 CHECK(!compiled_module->has_weak_owning_instance()); 1883 CHECK_NULL(GetOwningInstance(compiled_module));
1811 } 1884 }
1812 1885
1813 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) { 1886 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) {
1814 DisallowHeapAllocation no_gc; 1887 DisallowHeapAllocation no_gc;
1815 CHECK(IsWasmObject(*instance)); 1888 CHECK(IsWasmObject(*instance));
1816 WasmCompiledModule* compiled_module = 1889 FixedArray* compiled_module =
1817 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); 1890 FixedArray::cast(instance->GetInternalField(kWasmCompiledModule));
1818 CHECK(compiled_module->has_weak_module_object()); 1891 CHECK_NOT_NULL(GetModuleObject(compiled_module));
1819 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); 1892 CHECK(GetModuleObject(compiled_module)->cleared());
1820 } 1893 }
1821 1894
1822 } // namespace testing 1895 } // namespace testing
1823 } // namespace wasm 1896 } // namespace wasm
1824 } // namespace internal 1897 } // namespace internal
1825 } // namespace v8 1898 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698