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

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: 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
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 /*
22 static bool HasBrand(Isolate* isolate, Handle<Object> value,
23 Handle<Symbol> sym) {
24 if (value->IsJSObject()) {
25 Handle<JSObject> object = Handle<JSObject>::cast(value);
26 v8::Maybe<bool> has_brand = JSObject::HasOwnProperty(object, sym);
27 if (has_brand.IsNothing()) return false;
28 if (has_brand.ToChecked()) return true;
29 }
30 return false;
31 }
32 */
33
34 static uint32_t SafeUint32(Object* value) {
35 if (value->IsSmi()) {
36 int32_t val = Smi::cast(value)->value();
37 CHECK_GE(val, 0);
38 return static_cast<uint32_t>(val);
39 }
40 DCHECK(value->IsHeapNumber());
41 HeapNumber* num = HeapNumber::cast(value);
42 CHECK_GE(num->value(), 0.0);
43 CHECK_LE(num->value(), static_cast<double>(kMaxUInt32));
44 return static_cast<uint32_t>(num->value());
45 }
46
47 static int32_t SafeInt32(Object* value) {
48 if (value->IsSmi()) {
49 return Smi::cast(value)->value();
50 }
51 DCHECK(value->IsHeapNumber());
52 HeapNumber* num = HeapNumber::cast(value);
53 CHECK_GE(num->value(), static_cast<double>(Smi::kMinValue));
54 CHECK_LE(num->value(), static_cast<double>(Smi::kMaxValue));
55 return static_cast<int32_t>(num->value());
56 }
57
58 Handle<WasmModuleObject> WasmModuleObject::New(
59 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
60 ModuleOrigin origin = compiled_module->module()->origin;
61
62 Handle<JSObject> wasm_module;
63 if (origin == ModuleOrigin::kWasmOrigin) {
64 Handle<JSFunction> module_cons(
65 isolate->native_context()->wasm_module_constructor());
66 wasm_module = isolate->factory()->NewJSObject(module_cons);
67 } else {
68 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
69 Handle<Map> map = isolate->factory()->NewMap(
70 JS_OBJECT_TYPE,
71 JSObject::kHeaderSize + WasmModuleObject::kFieldCount * kPointerSize);
72 wasm_module = isolate->factory()->NewJSObjectFromMap(map, TENURED);
73 }
74 wasm_module->SetInternalField(WasmModuleObject::kCompiledModule,
75 *compiled_module);
76 if (origin == ModuleOrigin::kWasmOrigin) {
ahaas 2016/11/10 09:51:14 I think the code would be more readable if this {i
titzer 2016/11/10 10:33:25 Done.
77 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
78 Object::SetProperty(wasm_module, module_sym, wasm_module, STRICT).Check();
79 }
80 Handle<WeakCell> link_to_module =
81 isolate->factory()->NewWeakCell(wasm_module);
82 compiled_module->set_weak_wasm_module(link_to_module);
83 return Handle<WasmModuleObject>::cast(wasm_module);
84 }
85
86 WasmModuleObject* WasmModuleObject::cast(Object* object) {
87 DCHECK(object->IsJSObject());
88 // TODO(titzer): brand check for WasmModuleObject.
89 return reinterpret_cast<WasmModuleObject*>(object);
90 }
91
92 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial,
93 bool has_maximum, uint32_t maximum,
94 Handle<FixedArray>* js_functions) {
95 Handle<JSFunction> table_ctor(
96 isolate->native_context()->wasm_table_constructor());
97 Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor);
98 *js_functions = isolate->factory()->NewFixedArray(initial);
99 Object* null = isolate->heap()->null_value();
100 for (int i = 0; i < static_cast<int>(initial); ++i) {
101 (*js_functions)->set(i, null);
102 }
103 table_obj->SetInternalField(WasmTableObject::kArray, *(*js_functions));
ahaas 2016/11/10 09:51:14 Is there a reason why the field is called {WasmTab
titzer 2016/11/10 10:33:25 Done.
104 table_obj->SetInternalField(
105 WasmTableObject::kMaximum,
106 has_maximum ? static_cast<Object*>(Smi::FromInt(maximum))
107 : static_cast<Object*>(isolate->heap()->undefined_value()));
108 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0);
109 table_obj->SetInternalField(WasmTableObject::kDispatchTables,
110 *dispatch_tables);
111 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym());
112 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check();
113 return Handle<WasmTableObject>::cast(table_obj);
114 }
115
116 Handle<FixedArray> WasmTableObject::AddDispatchTable(
117 Isolate* isolate, Handle<WasmTableObject> table_obj,
118 Handle<WasmInstanceObject> instance, int table_index,
119 Handle<FixedArray> dispatch_table) {
120 Handle<FixedArray> dispatch_tables(
121 FixedArray::cast(table_obj->GetInternalField(kDispatchTables)), isolate);
122 DCHECK_EQ(0, dispatch_tables->length() % 3);
123
124 if (instance.is_null()) return dispatch_tables;
125 // TODO(titzer): use weak cells here to avoid leaking instances.
126
127 // Grow the dispatch table and add a new triple at the end.
128 Handle<FixedArray> new_dispatch_tables =
129 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3);
130
131 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance);
132 new_dispatch_tables->set(dispatch_tables->length() + 1,
133 Smi::FromInt(table_index));
134 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table);
135
136 table_obj->SetInternalField(WasmTableObject::kDispatchTables,
137 *new_dispatch_tables);
138
139 return new_dispatch_tables;
140 }
141 WasmTableObject* WasmTableObject::cast(Object* object) {
ahaas 2016/11/10 09:51:14 a newline is missing here.
titzer 2016/11/10 10:33:24 Done.
142 DCHECK(object->IsJSObject());
ahaas 2016/11/10 09:51:13 I think the DCHECK will crash if object is nullptr
titzer 2016/11/10 10:33:24 Done.
143 // TODO(titzer): brand check for WasmTableObject.
144 return reinterpret_cast<WasmTableObject*>(object);
145 }
146
147 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate,
148 Handle<JSArrayBuffer> buffer,
149 int maximum) {
150 Handle<JSFunction> memory_ctor(
151 isolate->native_context()->wasm_memory_constructor());
152 Handle<JSObject> memory_obj = isolate->factory()->NewJSObject(memory_ctor);
153 memory_obj->SetInternalField(kArrayBuffer, *buffer);
154 memory_obj->SetInternalField(kMaximum,
155 static_cast<Object*>(Smi::FromInt(maximum)));
156 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym());
157 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check();
158 return Handle<WasmMemoryObject>::cast(memory_obj);
159 }
160
161 JSArrayBuffer* WasmMemoryObject::get_buffer() {
162 return JSArrayBuffer::cast(GetInternalField(kArrayBuffer));
163 }
164
165 void WasmMemoryObject::set_buffer(JSArrayBuffer* buffer) {
166 SetInternalField(kArrayBuffer, buffer);
167 }
168
169 uint32_t WasmMemoryObject::current_pages() {
170 return SafeUint32(get_buffer()->byte_length()) / wasm::WasmModule::kPageSize;
171 }
172
173 int32_t WasmMemoryObject::maximum_pages() {
174 return SafeInt32(GetInternalField(kMaximum));
175 }
176
177 WasmMemoryObject* WasmMemoryObject::cast(Object* object) {
178 DCHECK(object->IsJSObject());
ahaas 2016/11/10 09:51:14 same here
titzer 2016/11/10 10:33:25 Done.
179 // TODO(titzer): brand check for WasmMemoryObject.
180 return reinterpret_cast<WasmMemoryObject*>(object);
181 }
182
183 WasmInstanceObject* WasmInstanceObject::cast(Object* object) {
184 DCHECK(IsWasmInstance(object));
ahaas 2016/11/10 09:51:13 same here
titzer 2016/11/10 10:33:25 Done.
185 return reinterpret_cast<WasmInstanceObject*>(object);
186 }
187
188 WasmExportedFunction* WasmExportedFunction::cast(Object* object) {
189 DCHECK(object->IsJSFunction());
ahaas 2016/11/10 09:51:14 same here
titzer 2016/11/10 10:33:25 Done.
190 // TODO(titzer): brand check for WasmExportedFunction.
191 return reinterpret_cast<WasmExportedFunction*>(object);
192 }
193
194 Handle<WasmCompiledModule> WasmCompiledModule::New(
195 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) {
196 Handle<FixedArray> ret =
197 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
198 // WasmCompiledModule::cast would fail since module bytes are not set yet.
199 Handle<WasmCompiledModule> compiled_module(
200 reinterpret_cast<WasmCompiledModule*>(*ret), isolate);
201 compiled_module->InitId();
202 compiled_module->set_module_wrapper(module_wrapper);
203 return compiled_module;
204 }
205
206 wasm::WasmModule* WasmCompiledModule::module() const {
207 return reinterpret_cast<WasmModuleWrapper*>(*module_wrapper())->get();
208 }
209
210 void WasmCompiledModule::InitId() {
211 #if DEBUG
212 static uint32_t instance_id_counter = 0;
213 set(kID_instance_id, Smi::FromInt(instance_id_counter++));
214 TRACE("New compiled module id: %d\n", instance_id());
215 #endif
216 }
217
218 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) {
219 if (!obj->IsFixedArray()) return false;
220 FixedArray* arr = FixedArray::cast(obj);
221 if (arr->length() != PropertyIndices::Count) return false;
222 Isolate* isolate = arr->GetIsolate();
223 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \
224 if (!arr->get(kID_##NAME)->IsSmi()) return false;
225 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \
226 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \
227 !arr->get(kID_##NAME)->Is##TYPE()) \
228 return false;
229 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME)
230 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME)
231 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME)
232 WCM_PROPERTY_TABLE(WCM_CHECK)
233 #undef WCM_CHECK
234
235 // All checks passed.
236 return true;
237 }
238
239 void WasmCompiledModule::PrintInstancesChain() {
240 #if DEBUG
241 if (!FLAG_trace_wasm_instances) return;
242 for (WasmCompiledModule* current = this; current != nullptr;) {
243 PrintF("->%d", current->instance_id());
244 if (current->ptr_to_weak_next_instance() == nullptr) break;
245 CHECK(!current->ptr_to_weak_next_instance()->cleared());
246 current =
247 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value());
248 }
249 PrintF("\n");
250 #endif
251 }
252
253 uint32_t WasmCompiledModule::mem_size() const {
254 return has_memory() ? memory()->byte_length()->Number() : default_mem_size();
255 }
256
257 uint32_t WasmCompiledModule::default_mem_size() const {
258 return min_mem_pages() * WasmModule::kPageSize;
259 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698