Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
dart::DeferredObject Class Reference

#include <deferred_objects.h>

Public Member Functions

 DeferredObject (intptr_t field_count, intptr_t *args)
 
intptr_t ArgumentCount () const
 
ObjectPtr object ()
 
void Fill ()
 

Detailed Description

Definition at line 185 of file deferred_objects.h.

Constructor & Destructor Documentation

◆ DeferredObject()

dart::DeferredObject::DeferredObject ( intptr_t  field_count,
intptr_t *  args 
)
inline

Definition at line 187 of file deferred_objects.h.

188 : field_count_(field_count),
189 args_(reinterpret_cast<ObjectPtr*>(args)),
190 object_(nullptr) {}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

Member Function Documentation

◆ ArgumentCount()

intptr_t dart::DeferredObject::ArgumentCount ( ) const
inline

Definition at line 192 of file deferred_objects.h.

192 {
193 return kFieldsStartIndex + kFieldEntrySize * field_count_;
194 }

◆ Fill()

void dart::DeferredObject::Fill ( )

Definition at line 292 of file deferred_objects.cc.

292 {
293 Create(); // Ensure instance is created.
294
295 Class& cls = Class::Handle();
296 cls ^= GetClass();
297
298 switch (cls.id()) {
299 case kContextCid: {
300 const Context& context = Context::Cast(*object_);
301
302 Smi& offset = Smi::Handle();
303 Object& value = Object::Handle();
304
305 for (intptr_t i = 0; i < field_count_; i++) {
306 offset ^= GetFieldOffset(i);
307 if (offset.Value() == Context::parent_offset()) {
308 // Copy parent.
309 Context& parent = Context::Handle();
310 parent ^= GetValue(i);
311 context.set_parent(parent);
312 if (FLAG_trace_deoptimization_verbose) {
313 OS::PrintErr(" ctx@parent (offset %" Pd ") <- %s\n",
314 offset.Value(), parent.ToCString());
315 }
316 } else {
317 intptr_t context_index = ToContextIndex(offset.Value());
318 value = GetValue(i);
319 context.SetAt(context_index, value);
320 if (FLAG_trace_deoptimization_verbose) {
321 OS::PrintErr(" ctx@%" Pd " (offset %" Pd ") <- %s\n",
322 context_index, offset.Value(), value.ToCString());
323 }
324 }
325 }
326 } break;
327 case kArrayCid: {
328 const Array& array = Array::Cast(*object_);
329
330 Smi& offset = Smi::Handle();
331 Object& value = Object::Handle();
332
333 for (intptr_t i = 0; i < field_count_; i++) {
334 offset ^= GetFieldOffset(i);
335 if (offset.Value() == Array::type_arguments_offset()) {
336 TypeArguments& type_args = TypeArguments::Handle();
337 type_args ^= GetValue(i);
338 array.SetTypeArguments(type_args);
339 if (FLAG_trace_deoptimization_verbose) {
340 OS::PrintErr(" array@type_args (offset %" Pd ") <- %s\n",
341 offset.Value(), type_args.ToCString());
342 }
343 } else {
344 const intptr_t index = Array::index_at_offset(offset.Value());
345 value = GetValue(i);
346 array.SetAt(index, value);
347 if (FLAG_trace_deoptimization_verbose) {
348 OS::PrintErr(" array@%" Pd " (offset %" Pd ") <- %s\n", index,
349 offset.Value(), value.ToCString());
350 }
351 }
352 }
353 } break;
354 case kPointerCid: {
355 auto* const zone = Thread::Current()->zone();
356 const int kDataIndex = 0;
357 const int kTypeArgIndex = 1;
358 ASSERT(field_count_ == 2);
359 ASSERT(Smi::Cast(Object::Handle(zone, GetFieldOffset(kDataIndex)))
360 .AsInt64Value() == PointerBase::data_offset());
361 ASSERT(Smi::Cast(Object::Handle(zone, GetFieldOffset(kTypeArgIndex)))
362 .AsInt64Value() == Pointer::type_arguments_offset());
363
364 const auto& pointer = Pointer::Cast(*object_);
365 const size_t address =
366 Integer::Cast(Object::Handle(zone, GetValue(kDataIndex)))
367 .AsInt64Value();
368 pointer.SetNativeAddress(address);
369 const auto& type_args = TypeArguments::Handle(
370 zone, IsolateGroup::Current()->object_store()->type_argument_never());
371 pointer.SetTypeArguments(type_args);
372 if (FLAG_trace_deoptimization_verbose) {
373 OS::PrintErr(" pointer@data <- 0x%" Px "\n", address);
374 OS::PrintErr(" pointer@type_args <- %s\n", type_args.ToCString());
375 }
376 } break;
377 case kRecordCid: {
378 const Record& record = Record::Cast(*object_);
379
380 Smi& offset = Smi::Handle();
381 Object& value = Object::Handle();
382
383 for (intptr_t i = 0; i < field_count_; i++) {
384 offset ^= GetFieldOffset(i);
385 const intptr_t index = Record::field_index_at_offset(offset.Value());
386 value = GetValue(i);
387 record.SetFieldAt(index, value);
388 if (FLAG_trace_deoptimization_verbose) {
389 OS::PrintErr(" record@%" Pd " (offset %" Pd ") <- %s\n", index,
390 offset.Value(), value.ToCString());
391 }
392 }
393 } break;
394 default:
395 if (IsTypedDataClassId(cls.id())) {
396 const TypedData& typed_data = TypedData::Cast(*object_);
397
398 Smi& offset = Smi::Handle();
399 Object& value = Object::Handle();
400 const auto cid = cls.id();
401
402 for (intptr_t i = 0; i < field_count_; i++) {
403 offset ^= GetFieldOffset(i);
404 const intptr_t element_offset = offset.Value();
405 value = GetValue(i);
406 switch (cid) {
407 case kTypedDataInt8ArrayCid:
408 typed_data.SetInt8(
409 element_offset,
410 static_cast<int8_t>(Integer::Cast(value).AsInt64Value()));
411 break;
412 case kTypedDataUint8ArrayCid:
413 case kTypedDataUint8ClampedArrayCid:
414 typed_data.SetUint8(
415 element_offset,
416 static_cast<uint8_t>(Integer::Cast(value).AsInt64Value()));
417 break;
418 case kTypedDataInt16ArrayCid:
419 typed_data.SetInt16(
420 element_offset,
421 static_cast<int16_t>(Integer::Cast(value).AsInt64Value()));
422 break;
423 case kTypedDataUint16ArrayCid:
424 typed_data.SetUint16(
425 element_offset,
426 static_cast<uint16_t>(Integer::Cast(value).AsInt64Value()));
427 break;
428 case kTypedDataInt32ArrayCid:
429 typed_data.SetInt32(
430 element_offset,
431 static_cast<int32_t>(Integer::Cast(value).AsInt64Value()));
432 break;
433 case kTypedDataUint32ArrayCid:
434 typed_data.SetUint32(
435 element_offset,
436 static_cast<uint32_t>(Integer::Cast(value).AsInt64Value()));
437 break;
438 case kTypedDataInt64ArrayCid:
439 typed_data.SetInt64(element_offset,
440 Integer::Cast(value).AsInt64Value());
441 break;
442 case kTypedDataUint64ArrayCid:
443 typed_data.SetUint64(
444 element_offset,
445 static_cast<uint64_t>(Integer::Cast(value).AsInt64Value()));
446 break;
447 case kTypedDataFloat32ArrayCid:
448 typed_data.SetFloat32(
449 element_offset,
450 static_cast<float>(Double::Cast(value).value()));
451 break;
452 case kTypedDataFloat64ArrayCid:
453 typed_data.SetFloat64(element_offset,
454 Double::Cast(value).value());
455 break;
456 case kTypedDataFloat32x4ArrayCid:
457 typed_data.SetFloat32x4(element_offset,
458 Float32x4::Cast(value).value());
459 break;
460 case kTypedDataInt32x4ArrayCid:
461 typed_data.SetInt32x4(element_offset,
462 Int32x4::Cast(value).value());
463 break;
464 case kTypedDataFloat64x2ArrayCid:
465 typed_data.SetFloat64x2(element_offset,
466 Float64x2::Cast(value).value());
467 break;
468 default:
469 UNREACHABLE();
470 }
471 if (FLAG_trace_deoptimization_verbose) {
472 OS::PrintErr(" typed_data (offset %" Pd ") <- %s\n",
473 element_offset, value.ToCString());
474 }
475 }
476 } else {
477 const Instance& obj = Instance::Cast(*object_);
478
479 Smi& offset = Smi::Handle();
480 Field& field = Field::Handle();
481 Object& value = Object::Handle();
482 const Array& offset_map = Array::Handle(cls.OffsetToFieldMap());
483
484 for (intptr_t i = 0; i < field_count_; i++) {
485 offset ^= GetFieldOffset(i);
486 field ^= offset_map.At(offset.Value() / kCompressedWordSize);
487 value = GetValue(i);
488 ASSERT((value.ptr() != Object::sentinel().ptr()) ||
489 (!field.IsNull() && field.is_late()));
490 if (!field.IsNull() && (value.ptr() != Object::sentinel().ptr())) {
491 obj.SetField(field, value);
492 if (FLAG_trace_deoptimization_verbose) {
493 OS::PrintErr(" %s <- %s\n",
494 String::Handle(field.name()).ToCString(),
495 value.ToCString());
496 }
497 } else {
498 // In addition to the type arguments vector we can also have lazy
499 // materialization of e.g. _ByteDataView objects which don't have
500 // explicit fields in Dart (all accesses to the fields are done via
501 // recognized native methods).
502 ASSERT(offset.Value() < cls.host_instance_size());
503 obj.SetFieldAtOffset(offset.Value(), value);
504 if (FLAG_trace_deoptimization_verbose) {
506 " %s @ offset(%" Pd ") <- %s\n",
507 (field.IsNull() ? "null Field"
508 : String::Handle(field.name()).ToCString()),
509 offset.Value(), value.ToCString());
510 }
511 }
512 }
513
514 if (obj.IsTypedDataView()) {
515 // The data field does not get materialized for typed data views
516 // because it is not a safe untagged pointer and must be recomputed.
517 TypedDataView::Cast(obj).RecomputeDataField();
518 }
519 }
520 break;
521 }
522}
#define UNREACHABLE()
Definition: assert.h:248
static intptr_t type_arguments_offset()
Definition: object.h:10928
static intptr_t index_at_offset(intptr_t offset_in_bytes)
Definition: object.h:10842
static intptr_t parent_offset()
Definition: object.h:7410
static IsolateGroup * Current()
Definition: isolate.h:539
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
virtual const char * ToCString() const
Definition: object.h:366
static Object & Handle()
Definition: object.h:407
static intptr_t data_offset()
Definition: object.h:11505
static intptr_t type_arguments_offset()
Definition: object.h:11902
static intptr_t field_index_at_offset(intptr_t offset_in_bytes)
Definition: object.h:11452
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
#define ASSERT(E)
uint8_t value
bool IsTypedDataClassId(intptr_t index)
Definition: class_id.h:433
static intptr_t ToContextIndex(intptr_t offset_in_bytes)
const intptr_t cid
static constexpr intptr_t kCompressedWordSize
Definition: globals.h:42
#define Px
Definition: globals.h:410
#define Pd
Definition: globals.h:408
SeparatedVector2 offset

◆ object()

ObjectPtr dart::DeferredObject::object ( )

Definition at line 214 of file deferred_objects.cc.

214 {
215 if (object_ == nullptr) {
216 Create();
217 }
218 return object_->ptr();
219}
ObjectPtr ptr() const
Definition: object.h:332

The documentation for this class was generated from the following files: