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

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

Issue 2490663002: [wasm] Move all heap-allocated WASM structures into wasm-objects.h. (Closed)
Patch Set: [wasm] Move all heap-allocated WASM structures into wasm-objects.h. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-objects.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/wasm/wasm-objects.h"
6 #include "src/wasm/wasm-module.h"
7
8 #define TRACE(...) \
9 do { \
10 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \
11 } while (false)
12
13 #define TRACE_CHAIN(instance) \
14 do { \
15 instance->PrintInstancesChain(); \
16 } while (false)
17
18 using namespace v8::internal;
19 using namespace v8::internal::wasm;
20
21 #define DEFINE_ACCESSORS(Container, name, field, type) \
22 type* Container::get_##name() { \
23 return type::cast(GetInternalField(field)); \
24 } \
25 void Container::set_##name(type* value) { \
26 return SetInternalField(field, value); \
27 }
28
29 #define DEFINE_OPTIONAL_ACCESSORS(Container, name, field, type) \
30 bool Container::has_##name() { \
31 return !GetInternalField(field)->IsUndefined(GetIsolate()); \
32 } \
33 type* Container::get_##name() { \
34 return type::cast(GetInternalField(field)); \
35 } \
36 void Container::set_##name(type* value) { \
37 return SetInternalField(field, value); \
38 }
39
40 #define DEFINE_GETTER(Container, name, field, type) \
41 type* Container::get_##name() { return type::cast(GetInternalField(field)); }
42
43 static uint32_t SafeUint32(Object* value) {
44 if (value->IsSmi()) {
45 int32_t val = Smi::cast(value)->value();
46 CHECK_GE(val, 0);
47 return static_cast<uint32_t>(val);
48 }
49 DCHECK(value->IsHeapNumber());
50 HeapNumber* num = HeapNumber::cast(value);
51 CHECK_GE(num->value(), 0.0);
52 CHECK_LE(num->value(), static_cast<double>(kMaxUInt32));
53 return static_cast<uint32_t>(num->value());
54 }
55
56 static int32_t SafeInt32(Object* value) {
57 if (value->IsSmi()) {
58 return Smi::cast(value)->value();
59 }
60 DCHECK(value->IsHeapNumber());
61 HeapNumber* num = HeapNumber::cast(value);
62 CHECK_GE(num->value(), static_cast<double>(Smi::kMinValue));
63 CHECK_LE(num->value(), static_cast<double>(Smi::kMaxValue));
64 return static_cast<int32_t>(num->value());
65 }
66
67 Handle<WasmModuleObject> WasmModuleObject::New(
68 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
69 ModuleOrigin origin = compiled_module->module()->origin;
70
71 Handle<JSObject> module_object;
72 if (origin == ModuleOrigin::kWasmOrigin) {
73 Handle<JSFunction> module_cons(
74 isolate->native_context()->wasm_module_constructor());
75 module_object = isolate->factory()->NewJSObject(module_cons);
76 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
77 Object::SetProperty(module_object, module_sym, module_object, STRICT)
78 .Check();
79 } else {
80 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
81 Handle<Map> map = isolate->factory()->NewMap(
82 JS_OBJECT_TYPE,
83 JSObject::kHeaderSize + WasmModuleObject::kFieldCount * kPointerSize);
84 module_object = isolate->factory()->NewJSObjectFromMap(map, TENURED);
85 }
86 module_object->SetInternalField(WasmModuleObject::kCompiledModule,
87 *compiled_module);
88 Handle<WeakCell> link_to_module =
89 isolate->factory()->NewWeakCell(module_object);
90 compiled_module->set_weak_wasm_module(link_to_module);
91 return Handle<WasmModuleObject>::cast(module_object);
92 }
93
94 WasmModuleObject* WasmModuleObject::cast(Object* object) {
95 DCHECK(object->IsJSObject());
96 // TODO(titzer): brand check for WasmModuleObject.
97 return reinterpret_cast<WasmModuleObject*>(object);
98 }
99
100 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial,
101 uint32_t maximum,
102 Handle<FixedArray>* js_functions) {
103 Handle<JSFunction> table_ctor(
104 isolate->native_context()->wasm_table_constructor());
105 Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor);
106 *js_functions = isolate->factory()->NewFixedArray(initial);
107 Object* null = isolate->heap()->null_value();
108 for (int i = 0; i < static_cast<int>(initial); ++i) {
109 (*js_functions)->set(i, null);
110 }
111 table_obj->SetInternalField(kFunctions, *(*js_functions));
112 table_obj->SetInternalField(kMaximum,
113 static_cast<Object*>(Smi::FromInt(maximum)));
114
115 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0);
116 table_obj->SetInternalField(kDispatchTables, *dispatch_tables);
117 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym());
118 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check();
119 return Handle<WasmTableObject>::cast(table_obj);
120 }
121
122 DEFINE_GETTER(WasmTableObject, dispatch_tables, kDispatchTables, FixedArray)
123
124 Handle<FixedArray> WasmTableObject::AddDispatchTable(
125 Isolate* isolate, Handle<WasmTableObject> table_obj,
126 Handle<WasmInstanceObject> instance, int table_index,
127 Handle<FixedArray> dispatch_table) {
128 Handle<FixedArray> dispatch_tables(
129 FixedArray::cast(table_obj->GetInternalField(kDispatchTables)), isolate);
130 DCHECK_EQ(0, dispatch_tables->length() % 3);
131
132 if (instance.is_null()) return dispatch_tables;
133 // TODO(titzer): use weak cells here to avoid leaking instances.
134
135 // Grow the dispatch table and add a new triple at the end.
136 Handle<FixedArray> new_dispatch_tables =
137 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3);
138
139 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance);
140 new_dispatch_tables->set(dispatch_tables->length() + 1,
141 Smi::FromInt(table_index));
142 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table);
143
144 table_obj->SetInternalField(WasmTableObject::kDispatchTables,
145 *new_dispatch_tables);
146
147 return new_dispatch_tables;
148 }
149
150 DEFINE_ACCESSORS(WasmTableObject, functions, kFunctions, FixedArray)
151
152 uint32_t WasmTableObject::current_length() { return get_functions()->length(); }
153
154 uint32_t WasmTableObject::maximum_length() {
155 return SafeUint32(GetInternalField(kMaximum));
156 }
157
158 WasmTableObject* WasmTableObject::cast(Object* object) {
159 DCHECK(object && object->IsJSObject());
160 // TODO(titzer): brand check for WasmTableObject.
161 return reinterpret_cast<WasmTableObject*>(object);
162 }
163
164 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate,
165 Handle<JSArrayBuffer> buffer,
166 int maximum) {
167 Handle<JSFunction> memory_ctor(
168 isolate->native_context()->wasm_memory_constructor());
169 Handle<JSObject> memory_obj = isolate->factory()->NewJSObject(memory_ctor);
170 memory_obj->SetInternalField(kArrayBuffer, *buffer);
171 memory_obj->SetInternalField(kMaximum,
172 static_cast<Object*>(Smi::FromInt(maximum)));
173 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym());
174 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check();
175 return Handle<WasmMemoryObject>::cast(memory_obj);
176 }
177
178 DEFINE_ACCESSORS(WasmMemoryObject, buffer, kArrayBuffer, JSArrayBuffer)
179
180 uint32_t WasmMemoryObject::current_pages() {
181 return SafeUint32(get_buffer()->byte_length()) / wasm::WasmModule::kPageSize;
182 }
183
184 int32_t WasmMemoryObject::maximum_pages() {
185 return SafeInt32(GetInternalField(kMaximum));
186 }
187
188 WasmMemoryObject* WasmMemoryObject::cast(Object* object) {
189 DCHECK(object && object->IsJSObject());
190 // TODO(titzer): brand check for WasmMemoryObject.
191 return reinterpret_cast<WasmMemoryObject*>(object);
192 }
193
194 void WasmMemoryObject::AddInstance(WasmInstanceObject* instance) {
195 // TODO(gdeepti): This should be a weak list of instance objects
196 // for instances that share memory.
197 SetInternalField(kInstance, instance);
198 }
199
200 DEFINE_ACCESSORS(WasmInstanceObject, compiled_module, kCompiledModule,
201 WasmCompiledModule)
202 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, globals_buffer,
203 kGlobalsArrayBuffer, JSArrayBuffer)
204 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, memory_buffer, kMemoryArrayBuffer,
205 JSArrayBuffer)
206 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, memory_object, kMemoryObject,
207 WasmMemoryObject)
208 DEFINE_OPTIONAL_ACCESSORS(WasmInstanceObject, debug_info, kDebugInfo,
209 WasmDebugInfo)
210
211 WasmModuleObject* WasmInstanceObject::module_object() {
212 return WasmModuleObject::cast(*get_compiled_module()->wasm_module());
213 }
214
215 WasmModule* WasmInstanceObject::module() {
216 return reinterpret_cast<WasmModuleWrapper*>(
217 *get_compiled_module()->module_wrapper())
218 ->get();
219 }
220
221 WasmInstanceObject* WasmInstanceObject::cast(Object* object) {
222 DCHECK(IsWasmInstanceObject(object));
223 return reinterpret_cast<WasmInstanceObject*>(object);
224 }
225
226 bool WasmInstanceObject::IsWasmInstanceObject(Object* object) {
227 if (!object->IsObject()) return false;
228 if (!object->IsJSObject()) return false;
229
230 JSObject* obj = JSObject::cast(object);
231 Isolate* isolate = obj->GetIsolate();
232 if (obj->GetInternalFieldCount() != kFieldCount) {
233 return false;
234 }
235
236 Object* mem = obj->GetInternalField(kMemoryArrayBuffer);
237 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) ||
238 !WasmCompiledModule::IsWasmCompiledModule(
239 obj->GetInternalField(kCompiledModule))) {
240 return false;
241 }
242
243 // All checks passed.
244 return true;
245 }
246
247 Handle<WasmInstanceObject> WasmInstanceObject::New(
248 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
249 Handle<Map> map = isolate->factory()->NewMap(
250 JS_OBJECT_TYPE, JSObject::kHeaderSize + kFieldCount * kPointerSize);
251 Handle<WasmInstanceObject> instance(
252 reinterpret_cast<WasmInstanceObject*>(
253 *isolate->factory()->NewJSObjectFromMap(map, TENURED)),
254 isolate);
255
256 instance->SetInternalField(kCompiledModule, *compiled_module);
257 instance->SetInternalField(kMemoryObject, isolate->heap()->undefined_value());
258 return instance;
259 }
260
261 WasmInstanceObject* WasmExportedFunction::instance() {
262 return WasmInstanceObject::cast(GetInternalField(kInstance));
263 }
264
265 int WasmExportedFunction::function_index() {
266 return SafeInt32(GetInternalField(kIndex));
267 }
268
269 WasmExportedFunction* WasmExportedFunction::cast(Object* object) {
270 DCHECK(object && object->IsJSFunction());
271 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION,
272 JSFunction::cast(object)->code()->kind());
273 // TODO(titzer): brand check for WasmExportedFunction.
274 return reinterpret_cast<WasmExportedFunction*>(object);
275 }
276
277 Handle<WasmExportedFunction> WasmExportedFunction::New(
278 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<String> name,
279 Handle<Code> export_wrapper, int arity, int func_index) {
280 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
281 Handle<SharedFunctionInfo> shared =
282 isolate->factory()->NewSharedFunctionInfo(name, export_wrapper, false);
283 shared->set_length(arity);
284 shared->set_internal_formal_parameter_count(arity);
285 Handle<JSFunction> function = isolate->factory()->NewFunction(
286 isolate->wasm_function_map(), name, export_wrapper);
287 function->set_shared(*shared);
288
289 function->SetInternalField(kInstance, *instance);
290 function->SetInternalField(kIndex, Smi::FromInt(func_index));
291 return Handle<WasmExportedFunction>::cast(function);
292 }
293
294 Handle<WasmCompiledModule> WasmCompiledModule::New(
295 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) {
296 Handle<FixedArray> ret =
297 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
298 // WasmCompiledModule::cast would fail since module bytes are not set yet.
299 Handle<WasmCompiledModule> compiled_module(
300 reinterpret_cast<WasmCompiledModule*>(*ret), isolate);
301 compiled_module->InitId();
302 compiled_module->set_module_wrapper(module_wrapper);
303 return compiled_module;
304 }
305
306 wasm::WasmModule* WasmCompiledModule::module() const {
307 return reinterpret_cast<WasmModuleWrapper*>(*module_wrapper())->get();
308 }
309
310 void WasmCompiledModule::InitId() {
311 #if DEBUG
312 static uint32_t instance_id_counter = 0;
313 set(kID_instance_id, Smi::FromInt(instance_id_counter++));
314 TRACE("New compiled module id: %d\n", instance_id());
315 #endif
316 }
317
318 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) {
319 if (!obj->IsFixedArray()) return false;
320 FixedArray* arr = FixedArray::cast(obj);
321 if (arr->length() != PropertyIndices::Count) return false;
322 Isolate* isolate = arr->GetIsolate();
323 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \
324 if (!arr->get(kID_##NAME)->IsSmi()) return false;
325 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \
326 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \
327 !arr->get(kID_##NAME)->Is##TYPE()) \
328 return false;
329 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME)
330 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME)
331 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME)
332 WCM_PROPERTY_TABLE(WCM_CHECK)
333 #undef WCM_CHECK
334
335 // All checks passed.
336 return true;
337 }
338
339 void WasmCompiledModule::PrintInstancesChain() {
340 #if DEBUG
341 if (!FLAG_trace_wasm_instances) return;
342 for (WasmCompiledModule* current = this; current != nullptr;) {
343 PrintF("->%d", current->instance_id());
344 if (current->ptr_to_weak_next_instance() == nullptr) break;
345 CHECK(!current->ptr_to_weak_next_instance()->cleared());
346 current =
347 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value());
348 }
349 PrintF("\n");
350 #endif
351 }
352
353 uint32_t WasmCompiledModule::mem_size() const {
354 return has_memory() ? memory()->byte_length()->Number() : default_mem_size();
355 }
356
357 uint32_t WasmCompiledModule::default_mem_size() const {
358 return min_mem_pages() * WasmModule::kPageSize;
359 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-objects.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698