| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "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 11 matching lines...) Expand all Loading... |
| 22 } while (false) | 22 } while (false) |
| 23 | 23 |
| 24 #define TRACE_CHAIN(instance) \ | 24 #define TRACE_CHAIN(instance) \ |
| 25 do { \ | 25 do { \ |
| 26 instance->PrintInstancesChain(); \ | 26 instance->PrintInstancesChain(); \ |
| 27 } while (false) | 27 } while (false) |
| 28 | 28 |
| 29 using namespace v8::internal; | 29 using namespace v8::internal; |
| 30 using namespace v8::internal::wasm; | 30 using namespace v8::internal::wasm; |
| 31 | 31 |
| 32 #define DEFINE_GETTER0(getter, Container, name, field, type) \ | |
| 33 type* Container::name() { return type::cast(getter(field)); } | |
| 34 | |
| 35 #define DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \ | |
| 36 DEFINE_GETTER0(getter, Container, name, field, type) \ | |
| 37 void Container::set_##name(type* value) { return setter(field, value); } | |
| 38 | |
| 39 #define DEFINE_OPTIONAL_ACCESSORS0(getter, setter, Container, name, field, \ | |
| 40 type) \ | |
| 41 DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \ | |
| 42 bool Container::has_##name() { \ | |
| 43 return !getter(field)->IsUndefined(GetIsolate()); \ | |
| 44 } | |
| 45 | |
| 46 #define DEFINE_OPTIONAL_GETTER0(getter, Container, name, field, type) \ | |
| 47 DEFINE_GETTER0(getter, Container, name, field, type) \ | |
| 48 bool Container::has_##name() { \ | |
| 49 return !getter(field)->IsUndefined(GetIsolate()); \ | |
| 50 } | |
| 51 | |
| 52 #define DEFINE_GETTER0(getter, Container, name, field, type) \ | |
| 53 type* Container::name() { return type::cast(getter(field)); } | |
| 54 | |
| 55 #define DEFINE_OBJ_GETTER(Container, name, field, type) \ | |
| 56 DEFINE_GETTER0(GetEmbedderField, Container, name, field, type) | |
| 57 #define DEFINE_OBJ_ACCESSORS(Container, name, field, type) \ | |
| 58 DEFINE_ACCESSORS0(GetEmbedderField, SetEmbedderField, Container, name, \ | |
| 59 field, type) | |
| 60 #define DEFINE_OPTIONAL_OBJ_ACCESSORS(Container, name, field, type) \ | |
| 61 DEFINE_OPTIONAL_ACCESSORS0(GetEmbedderField, SetEmbedderField, Container, \ | |
| 62 name, field, type) | |
| 63 #define DEFINE_ARR_GETTER(Container, name, field, type) \ | |
| 64 DEFINE_GETTER0(get, Container, name, field, type) | |
| 65 #define DEFINE_ARR_ACCESSORS(Container, name, field, type) \ | |
| 66 DEFINE_ACCESSORS0(get, set, Container, name, field, type) | |
| 67 #define DEFINE_OPTIONAL_ARR_ACCESSORS(Container, name, field, type) \ | |
| 68 DEFINE_OPTIONAL_ACCESSORS0(get, set, Container, name, field, type) | |
| 69 #define DEFINE_OPTIONAL_ARR_GETTER(Container, name, field, type) \ | |
| 70 DEFINE_OPTIONAL_GETTER0(get, Container, name, field, type) | |
| 71 | |
| 72 namespace { | 32 namespace { |
| 73 | 33 |
| 74 // An iterator that returns first the module itself, then all modules linked via | 34 // An iterator that returns first the module itself, then all modules linked via |
| 75 // next, then all linked via prev. | 35 // next, then all linked via prev. |
| 76 class CompiledModulesIterator | 36 class CompiledModulesIterator |
| 77 : public v8::base::iterator<std::input_iterator_tag, | 37 : public v8::base::iterator<std::input_iterator_tag, |
| 78 Handle<WasmCompiledModule>> { | 38 Handle<WasmCompiledModule>> { |
| 79 public: | 39 public: |
| 80 CompiledModulesIterator(Isolate* isolate, | 40 CompiledModulesIterator(Isolate* isolate, |
| 81 Handle<WasmCompiledModule> start_module, bool at_end) | 41 Handle<WasmCompiledModule> start_module, bool at_end) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 if (offset == static_cast<uint32_t>(offset_in_func)) return true; | 151 if (offset == static_cast<uint32_t>(offset_in_func)) return true; |
| 192 } | 152 } |
| 193 return false; | 153 return false; |
| 194 } | 154 } |
| 195 #endif // DEBUG | 155 #endif // DEBUG |
| 196 | 156 |
| 197 } // namespace | 157 } // namespace |
| 198 | 158 |
| 199 Handle<WasmModuleObject> WasmModuleObject::New( | 159 Handle<WasmModuleObject> WasmModuleObject::New( |
| 200 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { | 160 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { |
| 201 WasmModule* module = compiled_module->module(); | 161 Handle<JSFunction> module_cons( |
| 202 Handle<JSObject> module_object; | 162 isolate->native_context()->wasm_module_constructor()); |
| 203 if (module->is_wasm()) { | 163 auto module_object = Handle<WasmModuleObject>::cast( |
| 204 Handle<JSFunction> module_cons( | 164 isolate->factory()->NewJSObject(module_cons)); |
| 205 isolate->native_context()->wasm_module_constructor()); | 165 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); |
| 206 module_object = isolate->factory()->NewJSObject(module_cons); | 166 Object::SetProperty(module_object, module_sym, module_object, STRICT).Check(); |
| 207 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); | 167 module_object->set_compiled_module(*compiled_module); |
| 208 Object::SetProperty(module_object, module_sym, module_object, STRICT) | |
| 209 .Check(); | |
| 210 } else { | |
| 211 DCHECK(module->is_asm_js()); | |
| 212 Handle<Map> map = isolate->factory()->NewMap( | |
| 213 JS_OBJECT_TYPE, | |
| 214 JSObject::kHeaderSize + WasmModuleObject::kFieldCount * kPointerSize); | |
| 215 module_object = isolate->factory()->NewJSObjectFromMap(map, TENURED); | |
| 216 } | |
| 217 module_object->SetEmbedderField(WasmModuleObject::kCompiledModule, | |
| 218 *compiled_module); | |
| 219 Handle<WeakCell> link_to_module = | 168 Handle<WeakCell> link_to_module = |
| 220 isolate->factory()->NewWeakCell(module_object); | 169 isolate->factory()->NewWeakCell(module_object); |
| 221 compiled_module->set_weak_wasm_module(link_to_module); | 170 compiled_module->set_weak_wasm_module(link_to_module); |
| 222 return Handle<WasmModuleObject>::cast(module_object); | 171 return module_object; |
| 223 } | 172 } |
| 224 | 173 |
| 225 WasmModuleObject* WasmModuleObject::cast(Object* object) { | |
| 226 DCHECK(object->IsJSObject()); | |
| 227 // TODO(titzer): brand check for WasmModuleObject. | |
| 228 return reinterpret_cast<WasmModuleObject*>(object); | |
| 229 } | |
| 230 | |
| 231 bool WasmModuleObject::IsWasmModuleObject(Object* object) { | |
| 232 return object->IsJSObject() && | |
| 233 JSObject::cast(object)->GetEmbedderFieldCount() == kFieldCount; | |
| 234 } | |
| 235 | |
| 236 DEFINE_OBJ_GETTER(WasmModuleObject, compiled_module, kCompiledModule, | |
| 237 WasmCompiledModule) | |
| 238 | |
| 239 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial, | 174 Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial, |
| 240 int64_t maximum, | 175 int64_t maximum, |
| 241 Handle<FixedArray>* js_functions) { | 176 Handle<FixedArray>* js_functions) { |
| 242 Handle<JSFunction> table_ctor( | 177 Handle<JSFunction> table_ctor( |
| 243 isolate->native_context()->wasm_table_constructor()); | 178 isolate->native_context()->wasm_table_constructor()); |
| 244 Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor); | 179 auto table_obj = Handle<WasmTableObject>::cast( |
| 245 table_obj->SetEmbedderField(kWrapperTracerHeader, Smi::kZero); | 180 isolate->factory()->NewJSObject(table_ctor)); |
| 246 | 181 |
| 247 *js_functions = isolate->factory()->NewFixedArray(initial); | 182 *js_functions = isolate->factory()->NewFixedArray(initial); |
| 248 Object* null = isolate->heap()->null_value(); | 183 Object* null = isolate->heap()->null_value(); |
| 249 for (int i = 0; i < static_cast<int>(initial); ++i) { | 184 for (int i = 0; i < static_cast<int>(initial); ++i) { |
| 250 (*js_functions)->set(i, null); | 185 (*js_functions)->set(i, null); |
| 251 } | 186 } |
| 252 table_obj->SetEmbedderField(kFunctions, *(*js_functions)); | 187 table_obj->set_functions(**js_functions); |
| 253 Handle<Object> max = isolate->factory()->NewNumber(maximum); | 188 DCHECK_EQ(maximum, static_cast<int>(maximum)); |
| 254 table_obj->SetEmbedderField(kMaximum, *max); | 189 table_obj->set_maximum_length(static_cast<int>(maximum)); |
| 255 | 190 |
| 256 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0); | 191 Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0); |
| 257 table_obj->SetEmbedderField(kDispatchTables, *dispatch_tables); | 192 table_obj->set_dispatch_tables(*dispatch_tables); |
| 258 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym()); | 193 Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym()); |
| 259 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check(); | 194 Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check(); |
| 260 return Handle<WasmTableObject>::cast(table_obj); | 195 return Handle<WasmTableObject>::cast(table_obj); |
| 261 } | 196 } |
| 262 | 197 |
| 263 Handle<FixedArray> WasmTableObject::AddDispatchTable( | 198 Handle<FixedArray> WasmTableObject::AddDispatchTable( |
| 264 Isolate* isolate, Handle<WasmTableObject> table_obj, | 199 Isolate* isolate, Handle<WasmTableObject> table_obj, |
| 265 Handle<WasmInstanceObject> instance, int table_index, | 200 Handle<WasmInstanceObject> instance, int table_index, |
| 266 Handle<FixedArray> function_table, Handle<FixedArray> signature_table) { | 201 Handle<FixedArray> function_table, Handle<FixedArray> signature_table) { |
| 267 Handle<FixedArray> dispatch_tables( | 202 Handle<FixedArray> dispatch_tables(table_obj->dispatch_tables()); |
| 268 FixedArray::cast(table_obj->GetEmbedderField(kDispatchTables)), isolate); | |
| 269 DCHECK_EQ(0, dispatch_tables->length() % 4); | 203 DCHECK_EQ(0, dispatch_tables->length() % 4); |
| 270 | 204 |
| 271 if (instance.is_null()) return dispatch_tables; | 205 if (instance.is_null()) return dispatch_tables; |
| 272 // TODO(titzer): use weak cells here to avoid leaking instances. | 206 // TODO(titzer): use weak cells here to avoid leaking instances. |
| 273 | 207 |
| 274 // Grow the dispatch table and add a new entry at the end. | 208 // Grow the dispatch table and add a new entry at the end. |
| 275 Handle<FixedArray> new_dispatch_tables = | 209 Handle<FixedArray> new_dispatch_tables = |
| 276 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 4); | 210 isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 4); |
| 277 | 211 |
| 278 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance); | 212 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance); |
| 279 new_dispatch_tables->set(dispatch_tables->length() + 1, | 213 new_dispatch_tables->set(dispatch_tables->length() + 1, |
| 280 Smi::FromInt(table_index)); | 214 Smi::FromInt(table_index)); |
| 281 new_dispatch_tables->set(dispatch_tables->length() + 2, *function_table); | 215 new_dispatch_tables->set(dispatch_tables->length() + 2, *function_table); |
| 282 new_dispatch_tables->set(dispatch_tables->length() + 3, *signature_table); | 216 new_dispatch_tables->set(dispatch_tables->length() + 3, *signature_table); |
| 283 | 217 |
| 284 table_obj->SetEmbedderField(WasmTableObject::kDispatchTables, | 218 table_obj->set_dispatch_tables(*new_dispatch_tables); |
| 285 *new_dispatch_tables); | |
| 286 | 219 |
| 287 return new_dispatch_tables; | 220 return new_dispatch_tables; |
| 288 } | 221 } |
| 289 | 222 |
| 290 DEFINE_OBJ_ACCESSORS(WasmTableObject, functions, kFunctions, FixedArray) | |
| 291 | |
| 292 DEFINE_OBJ_GETTER(WasmTableObject, dispatch_tables, kDispatchTables, FixedArray) | |
| 293 | |
| 294 uint32_t WasmTableObject::current_length() { return functions()->length(); } | |
| 295 | |
| 296 bool WasmTableObject::has_maximum_length() { | |
| 297 return GetEmbedderField(kMaximum)->Number() >= 0; | |
| 298 } | |
| 299 | |
| 300 int64_t WasmTableObject::maximum_length() { | |
| 301 return static_cast<int64_t>(GetEmbedderField(kMaximum)->Number()); | |
| 302 } | |
| 303 | |
| 304 WasmTableObject* WasmTableObject::cast(Object* object) { | |
| 305 DCHECK(object && object->IsJSObject()); | |
| 306 // TODO(titzer): brand check for WasmTableObject. | |
| 307 return reinterpret_cast<WasmTableObject*>(object); | |
| 308 } | |
| 309 | |
| 310 void WasmTableObject::grow(Isolate* isolate, uint32_t count) { | 223 void WasmTableObject::grow(Isolate* isolate, uint32_t count) { |
| 311 Handle<FixedArray> dispatch_tables( | 224 Handle<FixedArray> dispatch_tables(this->dispatch_tables()); |
| 312 FixedArray::cast(GetEmbedderField(kDispatchTables))); | |
| 313 DCHECK_EQ(0, dispatch_tables->length() % 4); | 225 DCHECK_EQ(0, dispatch_tables->length() % 4); |
| 314 uint32_t old_size = functions()->length(); | 226 uint32_t old_size = functions()->length(); |
| 315 | 227 |
| 316 Zone specialization_zone(isolate->allocator(), ZONE_NAME); | 228 Zone specialization_zone(isolate->allocator(), ZONE_NAME); |
| 317 for (int i = 0; i < dispatch_tables->length(); i += 4) { | 229 for (int i = 0; i < dispatch_tables->length(); i += 4) { |
| 318 Handle<FixedArray> old_function_table( | 230 Handle<FixedArray> old_function_table( |
| 319 FixedArray::cast(dispatch_tables->get(i + 2))); | 231 FixedArray::cast(dispatch_tables->get(i + 2))); |
| 320 Handle<FixedArray> old_signature_table( | 232 Handle<FixedArray> old_signature_table( |
| 321 FixedArray::cast(dispatch_tables->get(i + 3))); | 233 FixedArray::cast(dispatch_tables->get(i + 3))); |
| 322 Handle<FixedArray> new_function_table = | 234 Handle<FixedArray> new_function_table = |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 code_specialization.ApplyToWholeInstance(*instance); | 311 code_specialization.ApplyToWholeInstance(*instance); |
| 400 } | 312 } |
| 401 | 313 |
| 402 } // namespace | 314 } // namespace |
| 403 | 315 |
| 404 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate, | 316 Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate, |
| 405 Handle<JSArrayBuffer> buffer, | 317 Handle<JSArrayBuffer> buffer, |
| 406 int32_t maximum) { | 318 int32_t maximum) { |
| 407 Handle<JSFunction> memory_ctor( | 319 Handle<JSFunction> memory_ctor( |
| 408 isolate->native_context()->wasm_memory_constructor()); | 320 isolate->native_context()->wasm_memory_constructor()); |
| 409 Handle<JSObject> memory_obj = | 321 auto memory_obj = Handle<WasmMemoryObject>::cast( |
| 410 isolate->factory()->NewJSObject(memory_ctor, TENURED); | 322 isolate->factory()->NewJSObject(memory_ctor, TENURED)); |
| 411 memory_obj->SetEmbedderField(kWrapperTracerHeader, Smi::kZero); | |
| 412 if (buffer.is_null()) { | 323 if (buffer.is_null()) { |
| 413 const bool enable_guard_regions = EnableGuardRegions(); | 324 const bool enable_guard_regions = EnableGuardRegions(); |
| 414 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false, | 325 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false, |
| 415 enable_guard_regions); | 326 enable_guard_regions); |
| 416 } | 327 } |
| 417 memory_obj->SetEmbedderField(kArrayBuffer, *buffer); | 328 memory_obj->set_array_buffer(*buffer); |
| 418 Handle<Object> max = isolate->factory()->NewNumber(maximum); | 329 memory_obj->set_maximum_pages(maximum); |
| 419 memory_obj->SetEmbedderField(kMaximum, *max); | |
| 420 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); | 330 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); |
| 421 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); | 331 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); |
| 422 return Handle<WasmMemoryObject>::cast(memory_obj); | 332 return Handle<WasmMemoryObject>::cast(memory_obj); |
| 423 } | 333 } |
| 424 | 334 |
| 425 DEFINE_OBJ_ACCESSORS(WasmMemoryObject, buffer, kArrayBuffer, JSArrayBuffer) | |
| 426 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmMemoryObject, instances_link, kInstancesLink, | |
| 427 WasmInstanceWrapper) | |
| 428 | |
| 429 uint32_t WasmMemoryObject::current_pages() { | 335 uint32_t WasmMemoryObject::current_pages() { |
| 430 uint32_t byte_length; | 336 uint32_t byte_length; |
| 431 CHECK(buffer()->byte_length()->ToUint32(&byte_length)); | 337 CHECK(array_buffer()->byte_length()->ToUint32(&byte_length)); |
| 432 return byte_length / wasm::WasmModule::kPageSize; | 338 return byte_length / wasm::WasmModule::kPageSize; |
| 433 } | 339 } |
| 434 | 340 |
| 435 bool WasmMemoryObject::has_maximum_pages() { | |
| 436 return GetEmbedderField(kMaximum)->Number() >= 0; | |
| 437 } | |
| 438 | |
| 439 int32_t WasmMemoryObject::maximum_pages() { | |
| 440 return static_cast<int32_t>(GetEmbedderField(kMaximum)->Number()); | |
| 441 } | |
| 442 | |
| 443 WasmMemoryObject* WasmMemoryObject::cast(Object* object) { | |
| 444 DCHECK(object && object->IsJSObject()); | |
| 445 // TODO(titzer): brand check for WasmMemoryObject. | |
| 446 return reinterpret_cast<WasmMemoryObject*>(object); | |
| 447 } | |
| 448 | |
| 449 void WasmMemoryObject::AddInstance(Isolate* isolate, | 341 void WasmMemoryObject::AddInstance(Isolate* isolate, |
| 450 Handle<WasmInstanceObject> instance) { | 342 Handle<WasmInstanceObject> instance) { |
| 451 Handle<WasmInstanceWrapper> instance_wrapper = | 343 Handle<WasmInstanceWrapper> instance_wrapper = |
| 452 handle(instance->instance_wrapper()); | 344 handle(instance->instance_wrapper()); |
| 453 if (has_instances_link()) { | 345 if (has_instances_link()) { |
| 454 Handle<WasmInstanceWrapper> current_wrapper(instances_link()); | 346 Handle<WasmInstanceWrapper> current_wrapper(instances_link()); |
| 455 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); | 347 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); |
| 456 DCHECK(!current_wrapper->has_previous()); | 348 DCHECK(!current_wrapper->has_previous()); |
| 457 instance_wrapper->set_next_wrapper(*current_wrapper); | 349 instance_wrapper->set_next_wrapper(*current_wrapper); |
| 458 current_wrapper->set_previous_wrapper(*instance_wrapper); | 350 current_wrapper->set_previous_wrapper(*instance_wrapper); |
| 459 } | 351 } |
| 460 set_instances_link(*instance_wrapper); | 352 set_instances_link(*instance_wrapper); |
| 461 } | 353 } |
| 462 | 354 |
| 463 void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) { | |
| 464 Handle<Object> undefined = isolate->factory()->undefined_value(); | |
| 465 SetEmbedderField(kInstancesLink, *undefined); | |
| 466 } | |
| 467 | |
| 468 // static | 355 // static |
| 469 int32_t WasmMemoryObject::Grow(Isolate* isolate, | 356 int32_t WasmMemoryObject::Grow(Isolate* isolate, |
| 470 Handle<WasmMemoryObject> memory_object, | 357 Handle<WasmMemoryObject> memory_object, |
| 471 uint32_t pages) { | 358 uint32_t pages) { |
| 472 Handle<JSArrayBuffer> old_buffer(memory_object->buffer()); | 359 Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer()); |
| 473 uint32_t old_size = 0; | 360 uint32_t old_size = 0; |
| 474 CHECK(old_buffer->byte_length()->ToUint32(&old_size)); | 361 CHECK(old_buffer->byte_length()->ToUint32(&old_size)); |
| 475 Handle<JSArrayBuffer> new_buffer; | 362 Handle<JSArrayBuffer> new_buffer; |
| 476 // Return current size if grow by 0. | 363 // Return current size if grow by 0. |
| 477 if (pages == 0) { | 364 if (pages == 0) { |
| 478 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same | 365 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same |
| 479 // backing store and neuter the old one to be spec compliant. | 366 // backing store and neuter the old one to be spec compliant. |
| 480 if (old_size != 0) { | 367 if (old_size != 0) { |
| 481 new_buffer = SetupArrayBuffer( | 368 new_buffer = SetupArrayBuffer( |
| 482 isolate, old_buffer->allocation_base(), | 369 isolate, old_buffer->allocation_base(), |
| 483 old_buffer->allocation_length(), old_buffer->backing_store(), | 370 old_buffer->allocation_length(), old_buffer->backing_store(), |
| 484 old_size, old_buffer->is_external(), old_buffer->has_guard_region()); | 371 old_size, old_buffer->is_external(), old_buffer->has_guard_region()); |
| 485 memory_object->set_buffer(*new_buffer); | 372 memory_object->set_array_buffer(*new_buffer); |
| 486 } | 373 } |
| 487 DCHECK_EQ(0, old_size % WasmModule::kPageSize); | 374 DCHECK_EQ(0, old_size % WasmModule::kPageSize); |
| 488 return old_size / WasmModule::kPageSize; | 375 return old_size / WasmModule::kPageSize; |
| 489 } | 376 } |
| 490 if (!memory_object->has_instances_link()) { | 377 if (!memory_object->has_instances_link()) { |
| 491 // Memory object does not have an instance associated with it, just grow | 378 // Memory object does not have an instance associated with it, just grow |
| 492 uint32_t max_pages; | 379 uint32_t max_pages; |
| 493 if (memory_object->has_maximum_pages()) { | 380 if (memory_object->has_maximum_pages()) { |
| 494 max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); | 381 max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); |
| 495 if (FLAG_wasm_max_mem_pages < max_pages) return -1; | 382 if (FLAG_wasm_max_mem_pages < max_pages) return -1; |
| 496 } else { | 383 } else { |
| 497 max_pages = FLAG_wasm_max_mem_pages; | 384 max_pages = FLAG_wasm_max_mem_pages; |
| 498 } | 385 } |
| 499 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); | 386 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); |
| 500 if (new_buffer.is_null()) return -1; | 387 if (new_buffer.is_null()) return -1; |
| 501 } else { | 388 } else { |
| 502 Handle<WasmInstanceWrapper> instance_wrapper( | 389 Handle<WasmInstanceWrapper> instance_wrapper( |
| 503 memory_object->instances_link()); | 390 memory_object->instances_link()); |
| 504 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 391 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); |
| 505 DCHECK(instance_wrapper->has_instance()); | 392 DCHECK(instance_wrapper->has_instance()); |
| 506 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | 393 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); |
| 507 DCHECK(IsWasmInstance(*instance)); | 394 DCHECK(instance->IsWasmInstanceObject()); |
| 508 uint32_t max_pages = instance->GetMaxMemoryPages(); | 395 uint32_t max_pages = instance->GetMaxMemoryPages(); |
| 509 | 396 |
| 510 // Grow memory object buffer and update instances associated with it. | 397 // Grow memory object buffer and update instances associated with it. |
| 511 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); | 398 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); |
| 512 if (new_buffer.is_null()) return -1; | 399 if (new_buffer.is_null()) return -1; |
| 513 DCHECK(!instance_wrapper->has_previous()); | 400 DCHECK(!instance_wrapper->has_previous()); |
| 514 SetInstanceMemory(isolate, instance, new_buffer); | 401 SetInstanceMemory(isolate, instance, new_buffer); |
| 515 Address old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 402 Address old_mem_start = static_cast<Address>(old_buffer->backing_store()); |
| 516 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 403 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); |
| 517 while (instance_wrapper->has_next()) { | 404 while (instance_wrapper->has_next()) { |
| 518 instance_wrapper = instance_wrapper->next_wrapper(); | 405 instance_wrapper = instance_wrapper->next_wrapper(); |
| 519 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 406 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); |
| 520 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | 407 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); |
| 521 DCHECK(IsWasmInstance(*instance)); | 408 DCHECK(instance->IsWasmInstanceObject()); |
| 522 SetInstanceMemory(isolate, instance, new_buffer); | 409 SetInstanceMemory(isolate, instance, new_buffer); |
| 523 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 410 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); |
| 524 } | 411 } |
| 525 } | 412 } |
| 526 memory_object->set_buffer(*new_buffer); | 413 memory_object->set_array_buffer(*new_buffer); |
| 527 DCHECK_EQ(0, old_size % WasmModule::kPageSize); | 414 DCHECK_EQ(0, old_size % WasmModule::kPageSize); |
| 528 return old_size / WasmModule::kPageSize; | 415 return old_size / WasmModule::kPageSize; |
| 529 } | 416 } |
| 530 | 417 |
| 531 DEFINE_OBJ_ACCESSORS(WasmInstanceObject, compiled_module, kCompiledModule, | |
| 532 WasmCompiledModule) | |
| 533 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, globals_buffer, | |
| 534 kGlobalsArrayBuffer, JSArrayBuffer) | |
| 535 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_buffer, | |
| 536 kMemoryArrayBuffer, JSArrayBuffer) | |
| 537 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_object, kMemoryObject, | |
| 538 WasmMemoryObject) | |
| 539 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, debug_info, kDebugInfo, | |
| 540 WasmDebugInfo) | |
| 541 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, instance_wrapper, | |
| 542 kWasmMemInstanceWrapper, WasmInstanceWrapper) | |
| 543 DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, directly_called_instances, | |
| 544 kDirectlyCalledInstances, FixedArray) | |
| 545 | |
| 546 WasmModuleObject* WasmInstanceObject::module_object() { | 418 WasmModuleObject* WasmInstanceObject::module_object() { |
| 547 return *compiled_module()->wasm_module(); | 419 return *compiled_module()->wasm_module(); |
| 548 } | 420 } |
| 549 | 421 |
| 550 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } | 422 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } |
| 551 | 423 |
| 552 Handle<WasmDebugInfo> WasmInstanceObject::GetOrCreateDebugInfo( | 424 Handle<WasmDebugInfo> WasmInstanceObject::GetOrCreateDebugInfo( |
| 553 Handle<WasmInstanceObject> instance) { | 425 Handle<WasmInstanceObject> instance) { |
| 554 if (instance->has_debug_info()) return handle(instance->debug_info()); | 426 if (instance->has_debug_info()) return handle(instance->debug_info()); |
| 555 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); | 427 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); |
| 556 DCHECK(instance->has_debug_info()); | 428 DCHECK(instance->has_debug_info()); |
| 557 return new_info; | 429 return new_info; |
| 558 } | 430 } |
| 559 | 431 |
| 560 WasmInstanceObject* WasmInstanceObject::cast(Object* object) { | |
| 561 DCHECK(IsWasmInstanceObject(object)); | |
| 562 return reinterpret_cast<WasmInstanceObject*>(object); | |
| 563 } | |
| 564 | |
| 565 bool WasmInstanceObject::IsWasmInstanceObject(Object* object) { | |
| 566 if (!object->IsJSObject()) return false; | |
| 567 | |
| 568 JSObject* obj = JSObject::cast(object); | |
| 569 Isolate* isolate = obj->GetIsolate(); | |
| 570 if (obj->GetEmbedderFieldCount() != kFieldCount) { | |
| 571 return false; | |
| 572 } | |
| 573 | |
| 574 Object* mem = obj->GetEmbedderField(kMemoryArrayBuffer); | |
| 575 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || | |
| 576 !WasmCompiledModule::IsWasmCompiledModule( | |
| 577 obj->GetEmbedderField(kCompiledModule))) { | |
| 578 return false; | |
| 579 } | |
| 580 | |
| 581 // All checks passed. | |
| 582 return true; | |
| 583 } | |
| 584 | |
| 585 Handle<WasmInstanceObject> WasmInstanceObject::New( | 432 Handle<WasmInstanceObject> WasmInstanceObject::New( |
| 586 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { | 433 Isolate* isolate, Handle<WasmCompiledModule> compiled_module) { |
| 587 Handle<JSFunction> instance_cons( | 434 Handle<JSFunction> instance_cons( |
| 588 isolate->native_context()->wasm_instance_constructor()); | 435 isolate->native_context()->wasm_instance_constructor()); |
| 589 Handle<JSObject> instance_object = | 436 Handle<JSObject> instance_object = |
| 590 isolate->factory()->NewJSObject(instance_cons, TENURED); | 437 isolate->factory()->NewJSObject(instance_cons, TENURED); |
| 591 instance_object->SetEmbedderField(kWrapperTracerHeader, Smi::kZero); | |
| 592 | 438 |
| 593 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym()); | 439 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym()); |
| 594 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT) | 440 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT) |
| 595 .Check(); | 441 .Check(); |
| 596 Handle<WasmInstanceObject> instance( | 442 Handle<WasmInstanceObject> instance( |
| 597 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate); | 443 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate); |
| 598 | 444 |
| 599 instance->SetEmbedderField(kCompiledModule, *compiled_module); | 445 instance->set_compiled_module(*compiled_module); |
| 600 instance->SetEmbedderField(kMemoryObject, isolate->heap()->undefined_value()); | |
| 601 Handle<WasmInstanceWrapper> instance_wrapper = | 446 Handle<WasmInstanceWrapper> instance_wrapper = |
| 602 WasmInstanceWrapper::New(isolate, instance); | 447 WasmInstanceWrapper::New(isolate, instance); |
| 603 instance->SetEmbedderField(kWasmMemInstanceWrapper, *instance_wrapper); | 448 instance->set_instance_wrapper(*instance_wrapper); |
| 604 return instance; | 449 return instance; |
| 605 } | 450 } |
| 606 | 451 |
| 607 int32_t WasmInstanceObject::GetMemorySize() { | 452 int32_t WasmInstanceObject::GetMemorySize() { |
| 608 if (!has_memory_buffer()) return 0; | 453 if (!has_memory_buffer()) return 0; |
| 609 uint32_t bytes = memory_buffer()->byte_length()->Number(); | 454 uint32_t bytes = memory_buffer()->byte_length()->Number(); |
| 610 DCHECK_EQ(0, bytes % WasmModule::kPageSize); | 455 DCHECK_EQ(0, bytes % WasmModule::kPageSize); |
| 611 return bytes / WasmModule::kPageSize; | 456 return bytes / WasmModule::kPageSize; |
| 612 } | 457 } |
| 613 | 458 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 } | 494 } |
| 650 uint32_t compiled_max_pages = compiled_module()->module()->max_mem_pages; | 495 uint32_t compiled_max_pages = compiled_module()->module()->max_mem_pages; |
| 651 Isolate* isolate = GetIsolate(); | 496 Isolate* isolate = GetIsolate(); |
| 652 assert(compiled_module()->module()->is_wasm()); | 497 assert(compiled_module()->module()->is_wasm()); |
| 653 isolate->counters()->wasm_wasm_max_mem_pages_count()->AddSample( | 498 isolate->counters()->wasm_wasm_max_mem_pages_count()->AddSample( |
| 654 compiled_max_pages); | 499 compiled_max_pages); |
| 655 if (compiled_max_pages != 0) return compiled_max_pages; | 500 if (compiled_max_pages != 0) return compiled_max_pages; |
| 656 return FLAG_wasm_max_mem_pages; | 501 return FLAG_wasm_max_mem_pages; |
| 657 } | 502 } |
| 658 | 503 |
| 659 WasmInstanceObject* WasmExportedFunction::instance() { | |
| 660 return WasmInstanceObject::cast(GetEmbedderField(kInstance)); | |
| 661 } | |
| 662 | |
| 663 int WasmExportedFunction::function_index() { | |
| 664 int32_t func_index; | |
| 665 CHECK(GetEmbedderField(kIndex)->ToInt32(&func_index)); | |
| 666 return func_index; | |
| 667 } | |
| 668 | |
| 669 WasmExportedFunction* WasmExportedFunction::cast(Object* object) { | 504 WasmExportedFunction* WasmExportedFunction::cast(Object* object) { |
| 670 DCHECK(object && object->IsJSFunction()); | 505 DCHECK(object && object->IsJSFunction()); |
| 671 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, | 506 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, |
| 672 JSFunction::cast(object)->code()->kind()); | 507 JSFunction::cast(object)->code()->kind()); |
| 673 // TODO(titzer): brand check for WasmExportedFunction. | 508 // TODO(titzer): brand check for WasmExportedFunction. |
| 674 return reinterpret_cast<WasmExportedFunction*>(object); | 509 return reinterpret_cast<WasmExportedFunction*>(object); |
| 675 } | 510 } |
| 676 | 511 |
| 677 Handle<WasmExportedFunction> WasmExportedFunction::New( | 512 Handle<WasmExportedFunction> WasmExportedFunction::New( |
| 678 Isolate* isolate, Handle<WasmInstanceObject> instance, | 513 Isolate* isolate, Handle<WasmInstanceObject> instance, |
| 679 MaybeHandle<String> maybe_name, int func_index, int arity, | 514 MaybeHandle<String> maybe_name, int func_index, int arity, |
| 680 Handle<Code> export_wrapper) { | 515 Handle<Code> export_wrapper) { |
| 681 Handle<String> name; | 516 Handle<String> name; |
| 682 if (maybe_name.is_null()) { | 517 if (maybe_name.is_null()) { |
| 683 EmbeddedVector<char, 16> buffer; | 518 EmbeddedVector<char, 16> buffer; |
| 684 int length = SNPrintF(buffer, "%d", func_index); | 519 int length = SNPrintF(buffer, "%d", func_index); |
| 685 name = isolate->factory() | 520 name = isolate->factory() |
| 686 ->NewStringFromOneByte( | 521 ->NewStringFromOneByte( |
| 687 Vector<uint8_t>::cast(buffer.SubVector(0, length))) | 522 Vector<uint8_t>::cast(buffer.SubVector(0, length))) |
| 688 .ToHandleChecked(); | 523 .ToHandleChecked(); |
| 689 } else { | 524 } else { |
| 690 name = maybe_name.ToHandleChecked(); | 525 name = maybe_name.ToHandleChecked(); |
| 691 } | 526 } |
| 692 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind()); | 527 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind()); |
| 693 Handle<SharedFunctionInfo> shared = | 528 Handle<SharedFunctionInfo> shared = |
| 694 isolate->factory()->NewSharedFunctionInfo(name, export_wrapper, false); | 529 isolate->factory()->NewSharedFunctionInfo(name, export_wrapper, false); |
| 695 shared->set_length(arity); | 530 shared->set_length(arity); |
| 696 shared->set_internal_formal_parameter_count(arity); | 531 shared->set_internal_formal_parameter_count(arity); |
| 697 Handle<JSFunction> function = isolate->factory()->NewFunction( | 532 Handle<JSFunction> js_function = isolate->factory()->NewFunction( |
| 698 isolate->wasm_function_map(), name, export_wrapper); | 533 isolate->wasm_function_map(), name, export_wrapper); |
| 699 function->SetEmbedderField(kWrapperTracerHeader, Smi::kZero); | 534 |
| 535 Handle<WasmExportedFunction> function( |
| 536 reinterpret_cast<WasmExportedFunction*>(*js_function), isolate); |
| 700 | 537 |
| 701 function->set_shared(*shared); | 538 function->set_shared(*shared); |
| 539 function->set_instance(*instance); |
| 540 function->set_function_index(func_index); |
| 702 | 541 |
| 703 function->SetEmbedderField(kInstance, *instance); | |
| 704 function->SetEmbedderField(kIndex, Smi::FromInt(func_index)); | |
| 705 return Handle<WasmExportedFunction>::cast(function); | 542 return Handle<WasmExportedFunction>::cast(function); |
| 706 } | 543 } |
| 707 | 544 |
| 708 bool WasmSharedModuleData::IsWasmSharedModuleData(Object* object) { | 545 bool WasmSharedModuleData::IsWasmSharedModuleData(Object* object) { |
| 709 if (!object->IsFixedArray()) return false; | 546 if (!object->IsFixedArray()) return false; |
| 710 FixedArray* arr = FixedArray::cast(object); | 547 FixedArray* arr = FixedArray::cast(object); |
| 711 if (arr->length() != kFieldCount) return false; | 548 if (arr->length() != kFieldCount) return false; |
| 712 Isolate* isolate = arr->GetIsolate(); | 549 Isolate* isolate = arr->GetIsolate(); |
| 713 if (!arr->get(kModuleWrapper)->IsForeign()) return false; | 550 if (!arr->get(kModuleWrapperIndex)->IsForeign()) return false; |
| 714 if (!arr->get(kModuleBytes)->IsUndefined(isolate) && | 551 if (!arr->get(kModuleBytesIndex)->IsUndefined(isolate) && |
| 715 !arr->get(kModuleBytes)->IsSeqOneByteString()) | 552 !arr->get(kModuleBytesIndex)->IsSeqOneByteString()) |
| 716 return false; | 553 return false; |
| 717 if (!arr->get(kScript)->IsScript()) return false; | 554 if (!arr->get(kScriptIndex)->IsScript()) return false; |
| 718 if (!arr->get(kAsmJsOffsetTable)->IsUndefined(isolate) && | 555 if (!arr->get(kAsmJsOffsetTableIndex)->IsUndefined(isolate) && |
| 719 !arr->get(kAsmJsOffsetTable)->IsByteArray()) | 556 !arr->get(kAsmJsOffsetTableIndex)->IsByteArray()) |
| 720 return false; | 557 return false; |
| 721 if (!arr->get(kBreakPointInfos)->IsUndefined(isolate) && | 558 if (!arr->get(kBreakPointInfosIndex)->IsUndefined(isolate) && |
| 722 !arr->get(kBreakPointInfos)->IsFixedArray()) | 559 !arr->get(kBreakPointInfosIndex)->IsFixedArray()) |
| 723 return false; | 560 return false; |
| 724 return true; | 561 return true; |
| 725 } | 562 } |
| 726 | 563 |
| 727 WasmSharedModuleData* WasmSharedModuleData::cast(Object* object) { | 564 WasmSharedModuleData* WasmSharedModuleData::cast(Object* object) { |
| 728 DCHECK(IsWasmSharedModuleData(object)); | 565 DCHECK(IsWasmSharedModuleData(object)); |
| 729 return reinterpret_cast<WasmSharedModuleData*>(object); | 566 return reinterpret_cast<WasmSharedModuleData*>(object); |
| 730 } | 567 } |
| 731 | 568 |
| 732 wasm::WasmModule* WasmSharedModuleData::module() { | 569 wasm::WasmModule* WasmSharedModuleData::module() { |
| 733 // We populate the kModuleWrapper field with a Foreign holding the | 570 // We populate the kModuleWrapper field with a Foreign holding the |
| 734 // address to the address of a WasmModule. This is because we can | 571 // address to the address of a WasmModule. This is because we can |
| 735 // handle both cases when the WasmModule's lifetime is managed through | 572 // handle both cases when the WasmModule's lifetime is managed through |
| 736 // a Managed<WasmModule> object, as well as cases when it's managed | 573 // a Managed<WasmModule> object, as well as cases when it's managed |
| 737 // by the embedder. CcTests fall into the latter case. | 574 // by the embedder. CcTests fall into the latter case. |
| 738 return *(reinterpret_cast<wasm::WasmModule**>( | 575 return *(reinterpret_cast<wasm::WasmModule**>( |
| 739 Foreign::cast(get(kModuleWrapper))->foreign_address())); | 576 Foreign::cast(get(kModuleWrapperIndex))->foreign_address())); |
| 740 } | 577 } |
| 741 | 578 |
| 742 DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, module_bytes, kModuleBytes, | |
| 743 SeqOneByteString); | |
| 744 DEFINE_ARR_GETTER(WasmSharedModuleData, script, kScript, Script); | |
| 745 DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, asm_js_offset_table, | |
| 746 kAsmJsOffsetTable, ByteArray); | |
| 747 DEFINE_OPTIONAL_ARR_GETTER(WasmSharedModuleData, breakpoint_infos, | |
| 748 kBreakPointInfos, FixedArray); | |
| 749 DEFINE_OPTIONAL_ARR_GETTER(WasmSharedModuleData, lazy_compilation_orchestrator, | |
| 750 kLazyCompilationOrchestrator, Foreign); | |
| 751 | |
| 752 Handle<WasmSharedModuleData> WasmSharedModuleData::New( | 579 Handle<WasmSharedModuleData> WasmSharedModuleData::New( |
| 753 Isolate* isolate, Handle<Foreign> module_wrapper, | 580 Isolate* isolate, Handle<Foreign> module_wrapper, |
| 754 Handle<SeqOneByteString> module_bytes, Handle<Script> script, | 581 Handle<SeqOneByteString> module_bytes, Handle<Script> script, |
| 755 Handle<ByteArray> asm_js_offset_table) { | 582 Handle<ByteArray> asm_js_offset_table) { |
| 756 Handle<FixedArray> arr = | 583 Handle<FixedArray> arr = |
| 757 isolate->factory()->NewFixedArray(kFieldCount, TENURED); | 584 isolate->factory()->NewFixedArray(kFieldCount, TENURED); |
| 758 arr->set(kWrapperTracerHeader, Smi::kZero); | 585 arr->set(kModuleWrapperIndex, *module_wrapper); |
| 759 arr->set(kModuleWrapper, *module_wrapper); | |
| 760 if (!module_bytes.is_null()) { | 586 if (!module_bytes.is_null()) { |
| 761 arr->set(kModuleBytes, *module_bytes); | 587 arr->set(kModuleBytesIndex, *module_bytes); |
| 762 } | 588 } |
| 763 if (!script.is_null()) { | 589 if (!script.is_null()) { |
| 764 arr->set(kScript, *script); | 590 arr->set(kScriptIndex, *script); |
| 765 } | 591 } |
| 766 if (!asm_js_offset_table.is_null()) { | 592 if (!asm_js_offset_table.is_null()) { |
| 767 arr->set(kAsmJsOffsetTable, *asm_js_offset_table); | 593 arr->set(kAsmJsOffsetTableIndex, *asm_js_offset_table); |
| 768 } | 594 } |
| 769 | 595 |
| 770 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*arr)); | 596 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*arr)); |
| 771 return Handle<WasmSharedModuleData>::cast(arr); | 597 return Handle<WasmSharedModuleData>::cast(arr); |
| 772 } | 598 } |
| 773 | 599 |
| 600 Foreign* WasmSharedModuleData::lazy_compilation_orchestrator() { |
| 601 return Foreign::cast(get(kLazyCompilationOrchestratorIndex)); |
| 602 } |
| 603 |
| 774 bool WasmSharedModuleData::is_asm_js() { | 604 bool WasmSharedModuleData::is_asm_js() { |
| 775 bool asm_js = module()->is_asm_js(); | 605 bool asm_js = module()->is_asm_js(); |
| 776 DCHECK_EQ(asm_js, script()->IsUserJavaScript()); | 606 DCHECK_EQ(asm_js, script()->IsUserJavaScript()); |
| 777 DCHECK_EQ(asm_js, has_asm_js_offset_table()); | 607 DCHECK_EQ(asm_js, has_asm_js_offset_table()); |
| 778 return asm_js; | 608 return asm_js; |
| 779 } | 609 } |
| 780 | 610 |
| 781 void WasmSharedModuleData::ReinitializeAfterDeserialization( | 611 void WasmSharedModuleData::ReinitializeAfterDeserialization( |
| 782 Isolate* isolate, Handle<WasmSharedModuleData> shared) { | 612 Isolate* isolate, Handle<WasmSharedModuleData> shared) { |
| 783 DCHECK(shared->get(kModuleWrapper)->IsUndefined(isolate)); | 613 DCHECK(shared->get(kModuleWrapperIndex)->IsUndefined(isolate)); |
| 784 #ifdef DEBUG | 614 #ifdef DEBUG |
| 785 // No BreakpointInfo objects should survive deserialization. | 615 // No BreakpointInfo objects should survive deserialization. |
| 786 if (shared->has_breakpoint_infos()) { | 616 if (shared->has_breakpoint_infos()) { |
| 787 for (int i = 0, e = shared->breakpoint_infos()->length(); i < e; ++i) { | 617 for (int i = 0, e = shared->breakpoint_infos()->length(); i < e; ++i) { |
| 788 DCHECK(shared->breakpoint_infos()->get(i)->IsUndefined(isolate)); | 618 DCHECK(shared->breakpoint_infos()->get(i)->IsUndefined(isolate)); |
| 789 } | 619 } |
| 790 } | 620 } |
| 791 #endif | 621 #endif |
| 792 | 622 |
| 793 shared->set(kBreakPointInfos, isolate->heap()->undefined_value()); | 623 shared->set(kBreakPointInfosIndex, isolate->heap()->undefined_value()); |
| 794 | 624 |
| 795 WasmModule* module = nullptr; | 625 WasmModule* module = nullptr; |
| 796 { | 626 { |
| 797 // We parse the module again directly from the module bytes, so | 627 // We parse the module again directly from the module bytes, so |
| 798 // the underlying storage must not be moved meanwhile. | 628 // the underlying storage must not be moved meanwhile. |
| 799 DisallowHeapAllocation no_allocation; | 629 DisallowHeapAllocation no_allocation; |
| 800 SeqOneByteString* module_bytes = shared->module_bytes(); | 630 SeqOneByteString* module_bytes = shared->module_bytes(); |
| 801 const byte* start = | 631 const byte* start = |
| 802 reinterpret_cast<const byte*>(module_bytes->GetCharsAddress()); | 632 reinterpret_cast<const byte*>(module_bytes->GetCharsAddress()); |
| 803 const byte* end = start + module_bytes->length(); | 633 const byte* end = start + module_bytes->length(); |
| 804 // TODO(titzer): remember the module origin in the compiled_module | 634 // TODO(titzer): remember the module origin in the compiled_module |
| 805 // For now, we assume serialized modules did not originate from asm.js. | 635 // For now, we assume serialized modules did not originate from asm.js. |
| 806 ModuleResult result = | 636 ModuleResult result = |
| 807 SyncDecodeWasmModule(isolate, start, end, false, kWasmOrigin); | 637 SyncDecodeWasmModule(isolate, start, end, false, kWasmOrigin); |
| 808 CHECK(result.ok()); | 638 CHECK(result.ok()); |
| 809 CHECK_NOT_NULL(result.val); | 639 CHECK_NOT_NULL(result.val); |
| 810 // Take ownership of the WasmModule and immediately transfer it to the | 640 // Take ownership of the WasmModule and immediately transfer it to the |
| 811 // WasmModuleWrapper below. | 641 // WasmModuleWrapper below. |
| 812 module = result.val.release(); | 642 module = result.val.release(); |
| 813 } | 643 } |
| 814 | 644 |
| 815 Handle<WasmModuleWrapper> module_wrapper = | 645 Handle<WasmModuleWrapper> module_wrapper = |
| 816 WasmModuleWrapper::New(isolate, module); | 646 WasmModuleWrapper::New(isolate, module); |
| 817 | 647 |
| 818 shared->set(kModuleWrapper, *module_wrapper); | 648 shared->set(kModuleWrapperIndex, *module_wrapper); |
| 819 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); | 649 DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); |
| 820 } | 650 } |
| 821 | 651 |
| 822 namespace { | 652 namespace { |
| 823 | 653 |
| 824 int GetBreakpointPos(Isolate* isolate, Object* break_point_info_or_undef) { | 654 int GetBreakpointPos(Isolate* isolate, Object* break_point_info_or_undef) { |
| 825 if (break_point_info_or_undef->IsUndefined(isolate)) return kMaxInt; | 655 if (break_point_info_or_undef->IsUndefined(isolate)) return kMaxInt; |
| 826 return BreakPointInfo::cast(break_point_info_or_undef)->source_position(); | 656 return BreakPointInfo::cast(break_point_info_or_undef)->source_position(); |
| 827 } | 657 } |
| 828 | 658 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 853 | 683 |
| 854 void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared, | 684 void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared, |
| 855 int position, | 685 int position, |
| 856 Handle<Object> break_point_object) { | 686 Handle<Object> break_point_object) { |
| 857 Isolate* isolate = shared->GetIsolate(); | 687 Isolate* isolate = shared->GetIsolate(); |
| 858 Handle<FixedArray> breakpoint_infos; | 688 Handle<FixedArray> breakpoint_infos; |
| 859 if (shared->has_breakpoint_infos()) { | 689 if (shared->has_breakpoint_infos()) { |
| 860 breakpoint_infos = handle(shared->breakpoint_infos(), isolate); | 690 breakpoint_infos = handle(shared->breakpoint_infos(), isolate); |
| 861 } else { | 691 } else { |
| 862 breakpoint_infos = isolate->factory()->NewFixedArray(4, TENURED); | 692 breakpoint_infos = isolate->factory()->NewFixedArray(4, TENURED); |
| 863 shared->set(kBreakPointInfos, *breakpoint_infos); | 693 shared->set(kBreakPointInfosIndex, *breakpoint_infos); |
| 864 } | 694 } |
| 865 | 695 |
| 866 int insert_pos = | 696 int insert_pos = |
| 867 FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); | 697 FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); |
| 868 | 698 |
| 869 // If a BreakPointInfo object already exists for this position, add the new | 699 // If a BreakPointInfo object already exists for this position, add the new |
| 870 // breakpoint object and return. | 700 // breakpoint object and return. |
| 871 if (insert_pos < breakpoint_infos->length() && | 701 if (insert_pos < breakpoint_infos->length() && |
| 872 GetBreakpointPos(isolate, breakpoint_infos->get(insert_pos)) == | 702 GetBreakpointPos(isolate, breakpoint_infos->get(insert_pos)) == |
| 873 position) { | 703 position) { |
| 874 Handle<BreakPointInfo> old_info( | 704 Handle<BreakPointInfo> old_info( |
| 875 BreakPointInfo::cast(breakpoint_infos->get(insert_pos)), isolate); | 705 BreakPointInfo::cast(breakpoint_infos->get(insert_pos)), isolate); |
| 876 BreakPointInfo::SetBreakPoint(old_info, break_point_object); | 706 BreakPointInfo::SetBreakPoint(old_info, break_point_object); |
| 877 return; | 707 return; |
| 878 } | 708 } |
| 879 | 709 |
| 880 // Enlarge break positions array if necessary. | 710 // Enlarge break positions array if necessary. |
| 881 bool need_realloc = !breakpoint_infos->get(breakpoint_infos->length() - 1) | 711 bool need_realloc = !breakpoint_infos->get(breakpoint_infos->length() - 1) |
| 882 ->IsUndefined(isolate); | 712 ->IsUndefined(isolate); |
| 883 Handle<FixedArray> new_breakpoint_infos = breakpoint_infos; | 713 Handle<FixedArray> new_breakpoint_infos = breakpoint_infos; |
| 884 if (need_realloc) { | 714 if (need_realloc) { |
| 885 new_breakpoint_infos = isolate->factory()->NewFixedArray( | 715 new_breakpoint_infos = isolate->factory()->NewFixedArray( |
| 886 2 * breakpoint_infos->length(), TENURED); | 716 2 * breakpoint_infos->length(), TENURED); |
| 887 shared->set(kBreakPointInfos, *new_breakpoint_infos); | 717 shared->set(kBreakPointInfosIndex, *new_breakpoint_infos); |
| 888 // Copy over the entries [0, insert_pos). | 718 // Copy over the entries [0, insert_pos). |
| 889 for (int i = 0; i < insert_pos; ++i) | 719 for (int i = 0; i < insert_pos; ++i) |
| 890 new_breakpoint_infos->set(i, breakpoint_infos->get(i)); | 720 new_breakpoint_infos->set(i, breakpoint_infos->get(i)); |
| 891 } | 721 } |
| 892 | 722 |
| 893 // Move elements [insert_pos+1, ...] up by one. | 723 // Move elements [insert_pos+1, ...] up by one. |
| 894 for (int i = insert_pos + 1; i < breakpoint_infos->length(); ++i) { | 724 for (int i = insert_pos + 1; i < breakpoint_infos->length(); ++i) { |
| 895 Object* entry = breakpoint_infos->get(i); | 725 Object* entry = breakpoint_infos->get(i); |
| 896 if (entry->IsUndefined(isolate)) break; | 726 if (entry->IsUndefined(isolate)) break; |
| 897 new_breakpoint_infos->set(i + 1, entry); | 727 new_breakpoint_infos->set(i + 1, entry); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 } | 769 } |
| 940 } | 770 } |
| 941 | 771 |
| 942 void WasmSharedModuleData::PrepareForLazyCompilation( | 772 void WasmSharedModuleData::PrepareForLazyCompilation( |
| 943 Handle<WasmSharedModuleData> shared) { | 773 Handle<WasmSharedModuleData> shared) { |
| 944 if (shared->has_lazy_compilation_orchestrator()) return; | 774 if (shared->has_lazy_compilation_orchestrator()) return; |
| 945 Isolate* isolate = shared->GetIsolate(); | 775 Isolate* isolate = shared->GetIsolate(); |
| 946 LazyCompilationOrchestrator* orch = new LazyCompilationOrchestrator(); | 776 LazyCompilationOrchestrator* orch = new LazyCompilationOrchestrator(); |
| 947 Handle<Managed<LazyCompilationOrchestrator>> orch_handle = | 777 Handle<Managed<LazyCompilationOrchestrator>> orch_handle = |
| 948 Managed<LazyCompilationOrchestrator>::New(isolate, orch); | 778 Managed<LazyCompilationOrchestrator>::New(isolate, orch); |
| 949 shared->set(WasmSharedModuleData::kLazyCompilationOrchestrator, *orch_handle); | 779 shared->set(kLazyCompilationOrchestratorIndex, *orch_handle); |
| 950 } | 780 } |
| 951 | 781 |
| 952 Handle<WasmCompiledModule> WasmCompiledModule::New( | 782 Handle<WasmCompiledModule> WasmCompiledModule::New( |
| 953 Isolate* isolate, Handle<WasmSharedModuleData> shared, | 783 Isolate* isolate, Handle<WasmSharedModuleData> shared, |
| 954 Handle<FixedArray> code_table, | 784 Handle<FixedArray> code_table, |
| 955 MaybeHandle<FixedArray> maybe_empty_function_tables, | 785 MaybeHandle<FixedArray> maybe_empty_function_tables, |
| 956 MaybeHandle<FixedArray> maybe_signature_tables) { | 786 MaybeHandle<FixedArray> maybe_signature_tables) { |
| 957 Handle<FixedArray> ret = | 787 Handle<FixedArray> ret = |
| 958 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); | 788 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); |
| 959 // WasmCompiledModule::cast would fail since fields are not set yet. | 789 // WasmCompiledModule::cast would fail since fields are not set yet. |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 instance->compiled_module()->shared()->lazy_compilation_orchestrator(); | 1398 instance->compiled_module()->shared()->lazy_compilation_orchestrator(); |
| 1569 LazyCompilationOrchestrator* orch = | 1399 LazyCompilationOrchestrator* orch = |
| 1570 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get(); | 1400 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get(); |
| 1571 return orch->CompileLazy(isolate, instance, caller, offset, func_index, | 1401 return orch->CompileLazy(isolate, instance, caller, offset, func_index, |
| 1572 patch_caller); | 1402 patch_caller); |
| 1573 } | 1403 } |
| 1574 | 1404 |
| 1575 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New( | 1405 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New( |
| 1576 Isolate* isolate, Handle<WasmInstanceObject> instance) { | 1406 Isolate* isolate, Handle<WasmInstanceObject> instance) { |
| 1577 Handle<FixedArray> array = | 1407 Handle<FixedArray> array = |
| 1578 isolate->factory()->NewFixedArray(kWrapperPropertyCount, TENURED); | 1408 isolate->factory()->NewFixedArray(kFieldCount, TENURED); |
| 1579 Handle<WasmInstanceWrapper> instance_wrapper( | 1409 Handle<WasmInstanceWrapper> instance_wrapper( |
| 1580 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate); | 1410 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate); |
| 1581 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); | 1411 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); |
| 1582 instance_wrapper->set(kWrapperInstanceObject, *cell); | 1412 instance_wrapper->set(kWrapperInstanceObjectIndex, *cell); |
| 1583 return instance_wrapper; | 1413 return instance_wrapper; |
| 1584 } | 1414 } |
| 1585 | 1415 |
| 1586 bool WasmInstanceWrapper::IsWasmInstanceWrapper(Object* obj) { | 1416 bool WasmInstanceWrapper::IsWasmInstanceWrapper(Object* obj) { |
| 1587 if (!obj->IsFixedArray()) return false; | 1417 if (!obj->IsFixedArray()) return false; |
| 1588 Handle<FixedArray> array = handle(FixedArray::cast(obj)); | 1418 Handle<FixedArray> array = handle(FixedArray::cast(obj)); |
| 1589 if (array->length() != kWrapperPropertyCount) return false; | 1419 if (array->length() != kFieldCount) return false; |
| 1590 if (!array->get(kWrapperInstanceObject)->IsWeakCell()) return false; | 1420 if (!array->get(kWrapperInstanceObjectIndex)->IsWeakCell()) return false; |
| 1591 Isolate* isolate = array->GetIsolate(); | 1421 Isolate* isolate = array->GetIsolate(); |
| 1592 if (!array->get(kNextInstanceWrapper)->IsUndefined(isolate) && | 1422 if (!array->get(kNextInstanceWrapperIndex)->IsUndefined(isolate) && |
| 1593 !array->get(kNextInstanceWrapper)->IsFixedArray()) | 1423 !array->get(kNextInstanceWrapperIndex)->IsFixedArray()) |
| 1594 return false; | 1424 return false; |
| 1595 if (!array->get(kPreviousInstanceWrapper)->IsUndefined(isolate) && | 1425 if (!array->get(kPreviousInstanceWrapperIndex)->IsUndefined(isolate) && |
| 1596 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) | 1426 !array->get(kPreviousInstanceWrapperIndex)->IsFixedArray()) |
| 1597 return false; | 1427 return false; |
| 1598 return true; | 1428 return true; |
| 1599 } | 1429 } |
| 1600 | |
| 1601 DEFINE_OPTIONAL_ARR_ACCESSORS(WasmDebugInfo, locals_names, kLocalsNames, | |
| 1602 FixedArray) | |
| OLD | NEW |