Line data Source code
1 : // Copyright 2012 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 : // Review notes:
6 : //
7 : // - The use of macros in these inline functions may seem superfluous
8 : // but it is absolutely needed to make sure gcc generates optimal
9 : // code. gcc is not happy when attempting to inline too deep.
10 : //
11 :
12 : #ifndef V8_OBJECTS_INL_H_
13 : #define V8_OBJECTS_INL_H_
14 :
15 : #include "src/objects.h"
16 :
17 : #include "src/base/bits.h"
18 : #include "src/base/tsan.h"
19 : #include "src/builtins/builtins.h"
20 : #include "src/contexts-inl.h"
21 : #include "src/conversions-inl.h"
22 : #include "src/feedback-vector-inl.h"
23 : #include "src/field-index-inl.h"
24 : #include "src/handles-inl.h"
25 : #include "src/heap/factory.h"
26 : #include "src/heap/heap-inl.h" // crbug.com/v8/8499
27 : #include "src/isolate-inl.h"
28 : #include "src/keys.h"
29 : #include "src/layout-descriptor-inl.h"
30 : #include "src/lookup-cache-inl.h"
31 : #include "src/lookup-inl.h"
32 : #include "src/maybe-handles-inl.h"
33 : #include "src/objects/bigint.h"
34 : #include "src/objects/descriptor-array-inl.h"
35 : #include "src/objects/embedder-data-array-inl.h"
36 : #include "src/objects/free-space-inl.h"
37 : #include "src/objects/heap-number-inl.h"
38 : #include "src/objects/heap-object.h" // TODO(jkummerow): See below [1].
39 : #include "src/objects/js-proxy-inl.h"
40 : #include "src/objects/literal-objects.h"
41 : #include "src/objects/maybe-object-inl.h"
42 : #include "src/objects/oddball-inl.h"
43 : #include "src/objects/ordered-hash-table-inl.h"
44 : #include "src/objects/regexp-match-info.h"
45 : #include "src/objects/scope-info.h"
46 : #include "src/objects/slots-inl.h"
47 : #include "src/objects/smi-inl.h"
48 : #include "src/objects/template-objects.h"
49 : #include "src/objects/templates.h"
50 : #include "src/property-details.h"
51 : #include "src/property.h"
52 : #include "src/prototype-inl.h"
53 : #include "src/roots-inl.h"
54 : #include "src/transitions-inl.h"
55 : #include "src/v8memory.h"
56 :
57 : // [1] This file currently contains the definitions of many
58 : // HeapObject::IsFoo() predicates, which in turn require #including
59 : // many other -inl.h files. Find a way to avoid this. Idea:
60 : // Since e.g. HeapObject::IsSeqString requires things from string-inl.h,
61 : // and presumably is mostly used from places that require/include string-inl.h
62 : // anyway, maybe that's where it should be defined?
63 :
64 : // Has to be the last include (doesn't have include guards):
65 : #include "src/objects/object-macros.h"
66 :
67 : namespace v8 {
68 : namespace internal {
69 :
70 4012081666 : PropertyDetails::PropertyDetails(Smi smi) { value_ = smi->value(); }
71 :
72 : Smi PropertyDetails::AsSmi() const {
73 : // Ensure the upper 2 bits have the same value by sign extending it. This is
74 : // necessary to be able to use the 31st bit of the property details.
75 933142197 : int value = value_ << 1;
76 933142197 : return Smi::FromInt(value >> 1);
77 : }
78 :
79 :
80 23118 : int PropertyDetails::field_width_in_words() const {
81 : DCHECK_EQ(location(), kField);
82 : if (!FLAG_unbox_double_fields) return 1;
83 : if (kDoubleSize == kTaggedSize) return 1;
84 : return representation().IsDouble() ? kDoubleSize / kTaggedSize : 1;
85 : }
86 :
87 : bool HeapObject::IsUncompiledData() const {
88 105426632 : return IsUncompiledDataWithoutPreparseData() ||
89 : IsUncompiledDataWithPreparseData();
90 : }
91 :
92 : bool HeapObject::IsSloppyArgumentsElements() const {
93 : return IsFixedArrayExact();
94 : }
95 :
96 : bool HeapObject::IsJSSloppyArgumentsObject() const {
97 : return IsJSArgumentsObject();
98 : }
99 :
100 : bool HeapObject::IsJSGeneratorObject() const {
101 31430637 : return map()->instance_type() == JS_GENERATOR_OBJECT_TYPE ||
102 20952089 : IsJSAsyncFunctionObject() || IsJSAsyncGeneratorObject();
103 : }
104 :
105 : bool HeapObject::IsDataHandler() const {
106 : return IsLoadHandler() || IsStoreHandler();
107 : }
108 :
109 : bool HeapObject::IsClassBoilerplate() const { return IsFixedArrayExact(); }
110 :
111 : bool HeapObject::IsExternal(Isolate* isolate) const {
112 303152 : return map()->FindRootMap(isolate) == isolate->heap()->external_map();
113 : }
114 :
115 : #define IS_TYPE_FUNCTION_DEF(type_) \
116 : bool Object::Is##type_() const { \
117 : return IsHeapObject() && HeapObject::cast(*this)->Is##type_(); \
118 : }
119 14140517345 : HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DEF)
120 : #undef IS_TYPE_FUNCTION_DEF
121 :
122 : #define IS_TYPE_FUNCTION_DEF(Type, Value) \
123 : bool Object::Is##Type(Isolate* isolate) const { \
124 : return Is##Type(ReadOnlyRoots(isolate->heap())); \
125 : } \
126 : bool Object::Is##Type(ReadOnlyRoots roots) const { \
127 : return *this == roots.Value(); \
128 : } \
129 : bool Object::Is##Type() const { \
130 : return IsHeapObject() && HeapObject::cast(*this)->Is##Type(); \
131 : } \
132 : bool HeapObject::Is##Type(Isolate* isolate) const { \
133 : return Object::Is##Type(isolate); \
134 : } \
135 : bool HeapObject::Is##Type(ReadOnlyRoots roots) const { \
136 : return Object::Is##Type(roots); \
137 : } \
138 : bool HeapObject::Is##Type() const { return Is##Type(GetReadOnlyRoots()); }
139 3233932098 : ODDBALL_LIST(IS_TYPE_FUNCTION_DEF)
140 : #undef IS_TYPE_FUNCTION_DEF
141 :
142 : bool Object::IsNullOrUndefined(Isolate* isolate) const {
143 : return IsNullOrUndefined(ReadOnlyRoots(isolate));
144 : }
145 :
146 : bool Object::IsNullOrUndefined(ReadOnlyRoots roots) const {
147 268290077 : return IsNull(roots) || IsUndefined(roots);
148 : }
149 :
150 : bool Object::IsNullOrUndefined() const {
151 : return IsHeapObject() && HeapObject::cast(*this)->IsNullOrUndefined();
152 : }
153 :
154 : bool HeapObject::IsNullOrUndefined(Isolate* isolate) const {
155 : return Object::IsNullOrUndefined(isolate);
156 : }
157 :
158 : bool HeapObject::IsNullOrUndefined(ReadOnlyRoots roots) const {
159 : return Object::IsNullOrUndefined(roots);
160 : }
161 :
162 : bool HeapObject::IsNullOrUndefined() const {
163 513 : return IsNullOrUndefined(GetReadOnlyRoots());
164 : }
165 :
166 : bool HeapObject::IsUniqueName() const {
167 9299202 : return IsInternalizedString() || IsSymbol();
168 : }
169 :
170 : bool HeapObject::IsFunction() const {
171 : STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
172 931617 : return map()->instance_type() >= FIRST_FUNCTION_TYPE;
173 : }
174 :
175 13828691 : bool HeapObject::IsCallable() const { return map()->is_callable(); }
176 :
177 6697699 : bool HeapObject::IsConstructor() const { return map()->is_constructor(); }
178 :
179 : bool HeapObject::IsModuleInfo() const {
180 : return map() == GetReadOnlyRoots().module_info_map();
181 : }
182 :
183 : bool HeapObject::IsTemplateInfo() const {
184 1029453 : return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
185 : }
186 :
187 : bool HeapObject::IsConsString() const {
188 95378668 : if (!IsString()) return false;
189 95378675 : return StringShape(String::cast(*this)).IsCons();
190 : }
191 :
192 : bool HeapObject::IsThinString() const {
193 161294555 : if (!IsString()) return false;
194 161290056 : return StringShape(String::cast(*this)).IsThin();
195 : }
196 :
197 : bool HeapObject::IsSlicedString() const {
198 5923284 : if (!IsString()) return false;
199 5923283 : return StringShape(String::cast(*this)).IsSliced();
200 : }
201 :
202 : bool HeapObject::IsSeqString() const {
203 7493603 : if (!IsString()) return false;
204 7493604 : return StringShape(String::cast(*this)).IsSequential();
205 : }
206 :
207 : bool HeapObject::IsSeqOneByteString() const {
208 71767311 : if (!IsString()) return false;
209 198356050 : return StringShape(String::cast(*this)).IsSequential() &&
210 128468724 : String::cast(*this)->IsOneByteRepresentation();
211 : }
212 :
213 : bool HeapObject::IsSeqTwoByteString() const {
214 1959936 : if (!IsString()) return false;
215 239332 : return StringShape(String::cast(*this)).IsSequential() &&
216 159388 : String::cast(*this)->IsTwoByteRepresentation();
217 : }
218 :
219 : bool HeapObject::IsExternalString() const {
220 364654117 : if (!IsString()) return false;
221 83271886 : return StringShape(String::cast(*this)).IsExternal();
222 : }
223 :
224 : bool HeapObject::IsExternalOneByteString() const {
225 7700227 : if (!IsString()) return false;
226 15408047 : return StringShape(String::cast(*this)).IsExternal() &&
227 7707821 : String::cast(*this)->IsOneByteRepresentation();
228 : }
229 :
230 : bool HeapObject::IsExternalTwoByteString() const {
231 7692691 : if (!IsString()) return false;
232 15385468 : return StringShape(String::cast(*this)).IsExternal() &&
233 7692771 : String::cast(*this)->IsTwoByteRepresentation();
234 : }
235 :
236 191681460 : bool Object::IsNumber() const { return IsSmi() || IsHeapNumber(); }
237 :
238 : bool Object::IsNumeric() const { return IsNumber() || IsBigInt(); }
239 :
240 : bool HeapObject::IsFiller() const {
241 244519667 : InstanceType instance_type = map()->instance_type();
242 244520241 : return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
243 : }
244 :
245 : bool HeapObject::IsJSWeakCollection() const {
246 180012 : return IsJSWeakMap() || IsJSWeakSet();
247 : }
248 :
249 0 : bool HeapObject::IsJSCollection() const { return IsJSMap() || IsJSSet(); }
250 :
251 : bool HeapObject::IsPromiseReactionJobTask() const {
252 2502479 : return IsPromiseFulfillReactionJobTask() || IsPromiseRejectReactionJobTask();
253 : }
254 :
255 : bool HeapObject::IsEnumCache() const { return IsTuple2(); }
256 :
257 : bool HeapObject::IsFrameArray() const { return IsFixedArrayExact(); }
258 :
259 : bool HeapObject::IsArrayList() const {
260 1883 : return map() == GetReadOnlyRoots().array_list_map() ||
261 1306 : *this == GetReadOnlyRoots().empty_fixed_array();
262 : }
263 :
264 : bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArrayExact(); }
265 :
266 0 : bool Object::IsLayoutDescriptor() const { return IsSmi() || IsByteArray(); }
267 :
268 : bool HeapObject::IsDeoptimizationData() const {
269 : // Must be a fixed array.
270 : if (!IsFixedArrayExact()) return false;
271 :
272 : // There's no sure way to detect the difference between a fixed array and
273 : // a deoptimization data array. Since this is used for asserts we can
274 : // check that the length is zero or else the fixed size plus a multiple of
275 : // the entry size.
276 : int length = FixedArray::cast(*this)->length();
277 : if (length == 0) return true;
278 :
279 : length -= DeoptimizationData::kFirstDeoptEntryIndex;
280 : return length >= 0 && length % DeoptimizationData::kDeoptEntrySize == 0;
281 : }
282 :
283 : bool HeapObject::IsHandlerTable() const {
284 : if (!IsFixedArrayExact()) return false;
285 : // There's actually no way to see the difference between a fixed array and
286 : // a handler table array.
287 : return true;
288 : }
289 :
290 : bool HeapObject::IsTemplateList() const {
291 : if (!IsFixedArrayExact()) return false;
292 : // There's actually no way to see the difference between a fixed array and
293 : // a template list.
294 : if (FixedArray::cast(*this)->length() < 1) return false;
295 : return true;
296 : }
297 :
298 : bool HeapObject::IsDependentCode() const {
299 : if (!IsWeakFixedArray()) return false;
300 : // There's actually no way to see the difference between a weak fixed array
301 : // and a dependent codes array.
302 : return true;
303 : }
304 :
305 : bool HeapObject::IsAbstractCode() const {
306 7532065 : return IsBytecodeArray() || IsCode();
307 : }
308 :
309 : bool HeapObject::IsStringWrapper() const {
310 1505506 : return IsJSValue() && JSValue::cast(*this)->value()->IsString();
311 : }
312 :
313 : bool HeapObject::IsBooleanWrapper() const {
314 21343 : return IsJSValue() && JSValue::cast(*this)->value()->IsBoolean();
315 : }
316 :
317 : bool HeapObject::IsScriptWrapper() const {
318 : return IsJSValue() && JSValue::cast(*this)->value()->IsScript();
319 : }
320 :
321 : bool HeapObject::IsNumberWrapper() const {
322 21235 : return IsJSValue() && JSValue::cast(*this)->value()->IsNumber();
323 : }
324 :
325 : bool HeapObject::IsBigIntWrapper() const {
326 21183 : return IsJSValue() && JSValue::cast(*this)->value()->IsBigInt();
327 : }
328 :
329 : bool HeapObject::IsSymbolWrapper() const {
330 21160 : return IsJSValue() && JSValue::cast(*this)->value()->IsSymbol();
331 : }
332 :
333 : bool HeapObject::IsBoolean() const {
334 97394500 : return IsOddball() &&
335 97394500 : ((Oddball::cast(*this)->kind() & Oddball::kNotBooleanMask) == 0);
336 : }
337 :
338 : bool HeapObject::IsJSArrayBufferView() const {
339 284841 : return IsJSDataView() || IsJSTypedArray();
340 : }
341 :
342 : bool HeapObject::IsStringSet() const { return IsHashTable(); }
343 :
344 : bool HeapObject::IsObjectHashSet() const { return IsHashTable(); }
345 :
346 : bool HeapObject::IsNormalizedMapCache() const {
347 : return NormalizedMapCache::IsNormalizedMapCache(*this);
348 : }
349 :
350 : bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
351 :
352 : bool HeapObject::IsMapCache() const { return IsHashTable(); }
353 :
354 : bool HeapObject::IsObjectHashTable() const { return IsHashTable(); }
355 :
356 : bool Object::IsHashTableBase() const { return IsHashTable(); }
357 :
358 : bool Object::IsSmallOrderedHashTable() const {
359 : return IsSmallOrderedHashSet() || IsSmallOrderedHashMap() ||
360 : IsSmallOrderedNameDictionary();
361 : }
362 :
363 : bool Object::IsPrimitive() const {
364 11056739 : return IsSmi() || HeapObject::cast(*this)->map()->IsPrimitiveMap();
365 : }
366 :
367 : // static
368 : Maybe<bool> Object::IsArray(Handle<Object> object) {
369 2394888 : if (object->IsSmi()) return Just(false);
370 1197426 : Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
371 2394852 : if (heap_object->IsJSArray()) return Just(true);
372 2335256 : if (!heap_object->IsJSProxy()) return Just(false);
373 1233 : return JSProxy::IsArray(Handle<JSProxy>::cast(object));
374 : }
375 :
376 87734459 : bool HeapObject::IsUndetectable() const { return map()->is_undetectable(); }
377 :
378 : bool HeapObject::IsAccessCheckNeeded() const {
379 35985771 : if (IsJSGlobalProxy()) {
380 56874 : const JSGlobalProxy proxy = JSGlobalProxy::cast(*this);
381 56874 : JSGlobalObject global = proxy->GetIsolate()->context()->global_object();
382 56874 : return proxy->IsDetachedFrom(global);
383 : }
384 35928897 : return map()->is_access_check_needed();
385 : }
386 :
387 : bool HeapObject::IsStruct() const {
388 : switch (map()->instance_type()) {
389 : #define MAKE_STRUCT_CASE(TYPE, Name, name) \
390 : case TYPE: \
391 : return true;
392 : STRUCT_LIST(MAKE_STRUCT_CASE)
393 : #undef MAKE_STRUCT_CASE
394 : // It is hard to include ALLOCATION_SITE_TYPE in STRUCT_LIST because
395 : // that macro is used for many things and AllocationSite needs a few
396 : // special cases.
397 : case ALLOCATION_SITE_TYPE:
398 : return true;
399 : case LOAD_HANDLER_TYPE:
400 : case STORE_HANDLER_TYPE:
401 : return true;
402 : case FEEDBACK_CELL_TYPE:
403 : return true;
404 : case CALL_HANDLER_INFO_TYPE:
405 : return true;
406 : default:
407 : return false;
408 : }
409 : }
410 :
411 : #define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
412 : bool Object::Is##Name() const { \
413 : return IsHeapObject() && HeapObject::cast(*this)->Is##Name(); \
414 : } \
415 : TYPE_CHECKER(Name)
416 1363277388 : STRUCT_LIST(MAKE_STRUCT_PREDICATE)
417 : #undef MAKE_STRUCT_PREDICATE
418 :
419 126441909 : double Object::Number() const {
420 : DCHECK(IsNumber());
421 : return IsSmi() ? static_cast<double>(Smi(this->ptr())->value())
422 367187796 : : HeapNumber::unchecked_cast(*this)->value();
423 : }
424 :
425 : bool Object::IsNaN() const {
426 4637 : return this->IsHeapNumber() && std::isnan(HeapNumber::cast(*this)->value());
427 : }
428 :
429 : bool Object::IsMinusZero() const {
430 6860 : return this->IsHeapNumber() &&
431 6860 : i::IsMinusZero(HeapNumber::cast(*this)->value());
432 : }
433 :
434 43049058214 : OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object)
435 : OBJECT_CONSTRUCTORS_IMPL(HashTableBase, FixedArray)
436 :
437 : template <typename Derived, typename Shape>
438 0 : HashTable<Derived, Shape>::HashTable(Address ptr) : HashTableBase(ptr) {
439 : SLOW_DCHECK(IsHashTable());
440 0 : }
441 :
442 : template <typename Derived, typename Shape>
443 0 : ObjectHashTableBase<Derived, Shape>::ObjectHashTableBase(Address ptr)
444 0 : : HashTable<Derived, Shape>(ptr) {}
445 :
446 87453 : ObjectHashTable::ObjectHashTable(Address ptr)
447 : : ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>(ptr) {
448 : SLOW_DCHECK(IsObjectHashTable());
449 87453 : }
450 :
451 151270 : EphemeronHashTable::EphemeronHashTable(Address ptr)
452 : : ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>(ptr) {
453 : SLOW_DCHECK(IsEphemeronHashTable());
454 151270 : }
455 :
456 7632 : ObjectHashSet::ObjectHashSet(Address ptr)
457 : : HashTable<ObjectHashSet, ObjectHashSetShape>(ptr) {
458 : SLOW_DCHECK(IsObjectHashSet());
459 7632 : }
460 :
461 1578276 : OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray)
462 101187528 : OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray)
463 :
464 597086 : NormalizedMapCache::NormalizedMapCache(Address ptr) : WeakFixedArray(ptr) {
465 : // TODO(jkummerow): Introduce IsNormalizedMapCache() and use
466 : // OBJECT_CONSTRUCTORS_IMPL macro?
467 597086 : }
468 :
469 : OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObject)
470 530218 : OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
471 : OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)
472 :
473 9448 : OBJECT_CONSTRUCTORS_IMPL(TemplateObjectDescription, Tuple2)
474 :
475 : // ------------------------------------
476 : // Cast operations
477 :
478 265016 : CAST_ACCESSOR(BigInt)
479 1214051 : CAST_ACCESSOR(ObjectBoilerplateDescription)
480 151276 : CAST_ACCESSOR(EphemeronHashTable)
481 21603076612 : CAST_ACCESSOR(HeapObject)
482 597086 : CAST_ACCESSOR(NormalizedMapCache)
483 2092969144 : CAST_ACCESSOR(Object)
484 7632 : CAST_ACCESSOR(ObjectHashSet)
485 87453 : CAST_ACCESSOR(ObjectHashTable)
486 789138 : CAST_ACCESSOR(RegExpMatchInfo)
487 50593790 : CAST_ACCESSOR(ScopeInfo)
488 4724 : CAST_ACCESSOR(TemplateObjectDescription)
489 :
490 : bool Object::HasValidElements() {
491 : // Dictionary is covered under FixedArray.
492 : return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
493 : }
494 :
495 : bool Object::KeyEquals(Object second) {
496 : Object first = *this;
497 : if (second->IsNumber()) {
498 : if (first->IsNumber()) return first->Number() == second->Number();
499 : Object temp = first;
500 : first = second;
501 : second = temp;
502 : }
503 : if (first->IsNumber()) {
504 : DCHECK_LE(0, first->Number());
505 : uint32_t expected = static_cast<uint32_t>(first->Number());
506 : uint32_t index;
507 : return Name::cast(second)->AsArrayIndex(&index) && index == expected;
508 : }
509 : return Name::cast(first)->Equals(Name::cast(second));
510 : }
511 :
512 11306240 : bool Object::FilterKey(PropertyFilter filter) {
513 : DCHECK(!IsPropertyCell());
514 11306240 : if (IsSymbol()) {
515 100991 : if (filter & SKIP_SYMBOLS) return true;
516 46359 : if (Symbol::cast(*this)->is_private()) return true;
517 : } else {
518 11205249 : if (filter & SKIP_STRINGS) return true;
519 : }
520 : return false;
521 : }
522 :
523 1942 : Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
524 : Representation representation) {
525 1942 : if (!representation.IsDouble()) return object;
526 : auto result = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
527 3884 : if (object->IsUninitialized(isolate)) {
528 : result->set_value_as_bits(kHoleNanInt64);
529 2500 : } else if (object->IsMutableHeapNumber()) {
530 : // Ensure that all bits of the double value are preserved.
531 : result->set_value_as_bits(
532 : MutableHeapNumber::cast(*object)->value_as_bits());
533 : } else {
534 2490 : result->set_value(object->Number());
535 : }
536 1942 : return result;
537 : }
538 :
539 6877732 : Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
540 : Representation representation) {
541 : DCHECK(!object->IsUninitialized(isolate));
542 6877732 : if (!representation.IsDouble()) {
543 : DCHECK(object->FitsRepresentation(representation));
544 6866885 : return object;
545 : }
546 : return isolate->factory()->NewHeapNumber(
547 10847 : MutableHeapNumber::cast(*object)->value());
548 : }
549 :
550 19042068 : Representation Object::OptimalRepresentation() {
551 19042068 : if (!FLAG_track_fields) return Representation::Tagged();
552 19042085 : if (IsSmi()) {
553 : return Representation::Smi();
554 28956302 : } else if (FLAG_track_double_fields && IsHeapNumber()) {
555 : return Representation::Double();
556 28924112 : } else if (FLAG_track_computed_fields && IsUninitialized()) {
557 : return Representation::None();
558 14239530 : } else if (FLAG_track_heap_object_fields) {
559 : DCHECK(IsHeapObject());
560 : return Representation::HeapObject();
561 : } else {
562 : return Representation::Tagged();
563 : }
564 : }
565 :
566 :
567 13216751 : ElementsKind Object::OptimalElementsKind() {
568 13216750 : if (IsSmi()) return PACKED_SMI_ELEMENTS;
569 2713230 : if (IsNumber()) return PACKED_DOUBLE_ELEMENTS;
570 1562075 : return PACKED_ELEMENTS;
571 : }
572 :
573 :
574 39632962 : bool Object::FitsRepresentation(Representation representation) {
575 39632962 : if (FLAG_track_fields && representation.IsSmi()) {
576 4248003 : return IsSmi();
577 35384959 : } else if (FLAG_track_double_fields && representation.IsDouble()) {
578 70168 : return IsMutableHeapNumber() || IsNumber();
579 35349875 : } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
580 34762250 : return IsHeapObject();
581 587625 : } else if (FLAG_track_fields && representation.IsNone()) {
582 : return false;
583 : }
584 396789 : return true;
585 : }
586 :
587 63691317 : bool Object::ToUint32(uint32_t* value) const {
588 63691317 : if (IsSmi()) {
589 48184489 : int num = Smi::ToInt(*this);
590 48184490 : if (num < 0) return false;
591 48164840 : *value = static_cast<uint32_t>(num);
592 48164840 : return true;
593 : }
594 15506838 : if (IsHeapNumber()) {
595 : double num = HeapNumber::cast(*this)->value();
596 6337 : return DoubleToUint32IfEqualToSelf(num, value);
597 : }
598 : return false;
599 : }
600 :
601 : // static
602 16202341 : MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
603 : Handle<Object> object,
604 : const char* method_name) {
605 32404682 : if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
606 14152 : return ToObject(isolate, object, isolate->native_context(), method_name);
607 : }
608 :
609 :
610 : // static
611 6415382 : MaybeHandle<Name> Object::ToName(Isolate* isolate, Handle<Object> input) {
612 12830778 : if (input->IsName()) return Handle<Name>::cast(input);
613 78286 : return ConvertToName(isolate, input);
614 : }
615 :
616 : // static
617 262772 : MaybeHandle<Object> Object::ToPropertyKey(Isolate* isolate,
618 : Handle<Object> value) {
619 967954 : if (value->IsSmi() || HeapObject::cast(*value)->IsName()) return value;
620 486 : return ConvertToPropertyKey(isolate, value);
621 : }
622 :
623 : // static
624 136085 : MaybeHandle<Object> Object::ToPrimitive(Handle<Object> input,
625 : ToPrimitiveHint hint) {
626 272170 : if (input->IsPrimitive()) return input;
627 6630 : return JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), hint);
628 : }
629 :
630 : // static
631 7483851 : MaybeHandle<Object> Object::ToNumber(Isolate* isolate, Handle<Object> input) {
632 14967702 : if (input->IsNumber()) return input; // Shortcut.
633 2693278 : return ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumber);
634 : }
635 :
636 : // static
637 2942 : MaybeHandle<Object> Object::ToNumeric(Isolate* isolate, Handle<Object> input) {
638 9288 : if (input->IsNumber() || input->IsBigInt()) return input; // Shortcut.
639 1423 : return ConvertToNumberOrNumeric(isolate, input, Conversion::kToNumeric);
640 : }
641 :
642 : // static
643 4090023 : MaybeHandle<Object> Object::ToInteger(Isolate* isolate, Handle<Object> input) {
644 8180046 : if (input->IsSmi()) return input;
645 107089 : return ConvertToInteger(isolate, input);
646 : }
647 :
648 : // static
649 2575 : MaybeHandle<Object> Object::ToInt32(Isolate* isolate, Handle<Object> input) {
650 5149 : if (input->IsSmi()) return input;
651 1466 : return ConvertToInt32(isolate, input);
652 : }
653 :
654 : // static
655 436893 : MaybeHandle<Object> Object::ToUint32(Isolate* isolate, Handle<Object> input) {
656 873822 : if (input->IsSmi()) return handle(Smi::cast(*input)->ToUint32Smi(), isolate);
657 436857 : return ConvertToUint32(isolate, input);
658 : }
659 :
660 : // static
661 15692442 : MaybeHandle<String> Object::ToString(Isolate* isolate, Handle<Object> input) {
662 31384909 : if (input->IsString()) return Handle<String>::cast(input);
663 8280172 : return ConvertToString(isolate, input);
664 : }
665 :
666 : // static
667 64733 : MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) {
668 129466 : if (input->IsSmi()) {
669 187233 : int value = std::max(Smi::ToInt(*input), 0);
670 62411 : return handle(Smi::FromInt(value), isolate);
671 : }
672 2322 : return ConvertToLength(isolate, input);
673 : }
674 :
675 : // static
676 11085 : MaybeHandle<Object> Object::ToIndex(Isolate* isolate, Handle<Object> input,
677 : MessageTemplate error_index) {
678 32020 : if (input->IsSmi() && Smi::ToInt(*input) >= 0) return input;
679 1293 : return ConvertToIndex(isolate, input, error_index);
680 : }
681 :
682 2399005 : MaybeHandle<Object> Object::GetProperty(Isolate* isolate, Handle<Object> object,
683 : Handle<Name> name) {
684 2399005 : LookupIterator it(isolate, object, name);
685 2494808 : if (!it.IsFound()) return it.factory()->undefined_value();
686 2303202 : return GetProperty(&it);
687 : }
688 :
689 1184915 : MaybeHandle<Object> Object::GetElement(Isolate* isolate, Handle<Object> object,
690 : uint32_t index) {
691 1184915 : LookupIterator it(isolate, object, index);
692 2364842 : if (!it.IsFound()) return it.factory()->undefined_value();
693 4988 : return GetProperty(&it);
694 : }
695 :
696 22625 : MaybeHandle<Object> Object::SetElement(Isolate* isolate, Handle<Object> object,
697 : uint32_t index, Handle<Object> value,
698 : LanguageMode language_mode) {
699 22625 : LookupIterator it(isolate, object, index);
700 22625 : MAYBE_RETURN_NULL(
701 : SetProperty(&it, value, language_mode, StoreOrigin::kMaybeKeyed));
702 22430 : return value;
703 : }
704 :
705 24080269 : ObjectSlot HeapObject::RawField(int byte_offset) const {
706 4255735951 : return ObjectSlot(FIELD_ADDR(this, byte_offset));
707 : }
708 :
709 19594485 : ObjectSlot HeapObject::RawField(const HeapObject obj, int byte_offset) {
710 867045787 : return ObjectSlot(FIELD_ADDR(obj, byte_offset));
711 : }
712 :
713 : MaybeObjectSlot HeapObject::RawMaybeWeakField(int byte_offset) const {
714 2606051775 : return MaybeObjectSlot(FIELD_ADDR(this, byte_offset));
715 : }
716 :
717 : MaybeObjectSlot HeapObject::RawMaybeWeakField(HeapObject obj, int byte_offset) {
718 77842656 : return MaybeObjectSlot(FIELD_ADDR(obj, byte_offset));
719 : }
720 :
721 232102722 : MapWord MapWord::FromMap(const Map map) { return MapWord(map.ptr()); }
722 :
723 116745330 : Map MapWord::ToMap() const { return Map::unchecked_cast(Object(value_)); }
724 :
725 760681246 : bool MapWord::IsForwardingAddress() const { return HAS_SMI_TAG(value_); }
726 :
727 116178106 : MapWord MapWord::FromForwardingAddress(HeapObject object) {
728 118113330 : return MapWord(object->ptr() - kHeapObjectTag);
729 : }
730 :
731 481979 : HeapObject MapWord::ToForwardingAddress() {
732 : DCHECK(IsForwardingAddress());
733 963958 : return HeapObject::FromAddress(value_);
734 : }
735 :
736 : #ifdef VERIFY_HEAP
737 : void HeapObject::VerifyObjectField(Isolate* isolate, int offset) {
738 : VerifyPointer(isolate, READ_FIELD(this, offset));
739 : }
740 :
741 : void HeapObject::VerifyMaybeObjectField(Isolate* isolate, int offset) {
742 : MaybeObject::VerifyMaybeObjectPointer(isolate, READ_WEAK_FIELD(this, offset));
743 : }
744 :
745 : void HeapObject::VerifySmiField(int offset) {
746 : CHECK(READ_FIELD(this, offset)->IsSmi());
747 : }
748 :
749 : #endif
750 :
751 787937652 : ReadOnlyRoots HeapObject::GetReadOnlyRoots() const {
752 : // TODO(v8:7464): When RO_SPACE is embedded, this will access a global
753 : // variable instead.
754 1575875396 : return ReadOnlyRoots(MemoryChunk::FromHeapObject(*this)->heap());
755 : }
756 :
757 22736580774 : Map HeapObject::map() const { return map_word().ToMap(); }
758 :
759 6326630 : void HeapObject::set_map(Map value) {
760 : if (!value.is_null()) {
761 : #ifdef VERIFY_HEAP
762 : Heap::FromWritableHeapObject(*this)->VerifyObjectLayoutChange(*this, value);
763 : #endif
764 : }
765 : set_map_word(MapWord::FromMap(value));
766 6326630 : if (!value.is_null()) {
767 : // TODO(1600) We are passing kNullAddress as a slot because maps can never
768 : // be on an evacuation candidate.
769 6326630 : MarkingBarrier(*this, ObjectSlot(kNullAddress), value);
770 : }
771 6326630 : }
772 :
773 : Map HeapObject::synchronized_map() const {
774 : return synchronized_map_word().ToMap();
775 : }
776 :
777 59631753 : void HeapObject::synchronized_set_map(Map value) {
778 : if (!value.is_null()) {
779 : #ifdef VERIFY_HEAP
780 : Heap::FromWritableHeapObject(*this)->VerifyObjectLayoutChange(*this, value);
781 : #endif
782 : }
783 : synchronized_set_map_word(MapWord::FromMap(value));
784 59631753 : if (!value.is_null()) {
785 : // TODO(1600) We are passing kNullAddress as a slot because maps can never
786 : // be on an evacuation candidate.
787 59631775 : MarkingBarrier(*this, ObjectSlot(kNullAddress), value);
788 : }
789 59631756 : }
790 :
791 :
792 : // Unsafe accessor omitting write barrier.
793 : void HeapObject::set_map_no_write_barrier(Map value) {
794 : if (!value.is_null()) {
795 : #ifdef VERIFY_HEAP
796 : Heap::FromWritableHeapObject(*this)->VerifyObjectLayoutChange(*this, value);
797 : #endif
798 : }
799 : set_map_word(MapWord::FromMap(value));
800 : }
801 :
802 407005434 : void HeapObject::set_map_after_allocation(Map value, WriteBarrierMode mode) {
803 : set_map_word(MapWord::FromMap(value));
804 407005434 : if (mode != SKIP_WRITE_BARRIER) {
805 : DCHECK(!value.is_null());
806 : // TODO(1600) We are passing kNullAddress as a slot because maps can never
807 : // be on an evacuation candidate.
808 27501440 : MarkingBarrier(*this, ObjectSlot(kNullAddress), value);
809 : }
810 407005424 : }
811 :
812 374817793 : MapWordSlot HeapObject::map_slot() const {
813 24692849922 : return MapWordSlot(FIELD_ADDR(*this, kMapOffset));
814 : }
815 :
816 : MapWord HeapObject::map_word() const {
817 : return MapWord(map_slot().Relaxed_Load().ptr());
818 : }
819 :
820 116025717 : void HeapObject::set_map_word(MapWord map_word) {
821 116025717 : map_slot().Relaxed_Store(Object(map_word.value_));
822 116025717 : }
823 :
824 :
825 997537 : MapWord HeapObject::synchronized_map_word() const {
826 997537 : return MapWord(map_slot().Acquire_Load().ptr());
827 : }
828 :
829 : void HeapObject::synchronized_set_map_word(MapWord map_word) {
830 : map_slot().Release_Store(Object(map_word.value_));
831 : }
832 :
833 1780353230 : int HeapObject::Size() const { return SizeFromMap(map()); }
834 :
835 : inline bool IsSpecialReceiverInstanceType(InstanceType instance_type) {
836 96650 : return instance_type <= LAST_SPECIAL_RECEIVER_TYPE;
837 : }
838 :
839 : // This should be in objects/map-inl.h, but can't, because of a cyclic
840 : // dependency.
841 96650 : bool Map::IsSpecialReceiverMap() const {
842 : bool result = IsSpecialReceiverInstanceType(instance_type());
843 : DCHECK_IMPLIES(!result,
844 : !has_named_interceptor() && !is_access_check_needed());
845 96650 : return result;
846 : }
847 :
848 : inline bool IsCustomElementsReceiverInstanceType(InstanceType instance_type) {
849 422516 : return instance_type <= LAST_CUSTOM_ELEMENTS_RECEIVER;
850 : }
851 :
852 : // This should be in objects/map-inl.h, but can't, because of a cyclic
853 : // dependency.
854 422516 : bool Map::IsCustomElementsReceiverMap() const {
855 422516 : return IsCustomElementsReceiverInstanceType(instance_type());
856 : }
857 :
858 102070 : bool Object::ToArrayLength(uint32_t* index) const {
859 8250036 : return Object::ToUint32(index);
860 : }
861 :
862 2647 : bool Object::ToArrayIndex(uint32_t* index) const {
863 55406179 : return Object::ToUint32(index) && *index != kMaxUInt32;
864 : }
865 :
866 5914084386 : bool Object::GetHeapObjectIfStrong(HeapObject* result) const {
867 5914084386 : return GetHeapObject(result);
868 : }
869 :
870 6950491478 : bool Object::GetHeapObject(HeapObject* result) const {
871 6952490531 : if (!IsHeapObject()) return false;
872 6394600988 : *result = HeapObject::cast(*this);
873 6394600988 : return true;
874 : }
875 :
876 0 : HeapObject Object::GetHeapObject() const {
877 : DCHECK(IsHeapObject());
878 0 : return HeapObject::cast(*this);
879 : }
880 :
881 : void Object::VerifyApiCallResultType() {
882 : #if DEBUG
883 : if (IsSmi()) return;
884 : DCHECK(IsHeapObject());
885 : if (!(IsString() || IsSymbol() || IsJSReceiver() || IsHeapNumber() ||
886 : IsBigInt() || IsUndefined() || IsTrue() || IsFalse() || IsNull())) {
887 : FATAL("API call returned invalid object");
888 : }
889 : #endif // DEBUG
890 : }
891 :
892 255545 : int RegExpMatchInfo::NumberOfCaptureRegisters() {
893 : DCHECK_GE(length(), kLastMatchOverhead);
894 255545 : Object obj = get(kNumberOfCapturesIndex);
895 255545 : return Smi::ToInt(obj);
896 : }
897 :
898 : void RegExpMatchInfo::SetNumberOfCaptureRegisters(int value) {
899 : DCHECK_GE(length(), kLastMatchOverhead);
900 : set(kNumberOfCapturesIndex, Smi::FromInt(value));
901 : }
902 :
903 379715 : String RegExpMatchInfo::LastSubject() {
904 : DCHECK_GE(length(), kLastMatchOverhead);
905 379715 : return String::cast(get(kLastSubjectIndex));
906 : }
907 :
908 : void RegExpMatchInfo::SetLastSubject(String value) {
909 : DCHECK_GE(length(), kLastMatchOverhead);
910 182466 : set(kLastSubjectIndex, value);
911 : }
912 :
913 : Object RegExpMatchInfo::LastInput() {
914 : DCHECK_GE(length(), kLastMatchOverhead);
915 : return get(kLastInputIndex);
916 : }
917 :
918 : void RegExpMatchInfo::SetLastInput(Object value) {
919 : DCHECK_GE(length(), kLastMatchOverhead);
920 182511 : set(kLastInputIndex, value);
921 : }
922 :
923 636903 : int RegExpMatchInfo::Capture(int i) {
924 : DCHECK_LT(i, NumberOfCaptureRegisters());
925 1273806 : Object obj = get(kFirstCaptureIndex + i);
926 636903 : return Smi::ToInt(obj);
927 : }
928 :
929 2690380 : void RegExpMatchInfo::SetCapture(int i, int value) {
930 : DCHECK_LT(i, NumberOfCaptureRegisters());
931 : set(kFirstCaptureIndex + i, Smi::FromInt(value));
932 2690380 : }
933 :
934 20 : WriteBarrierMode HeapObject::GetWriteBarrierMode(
935 : const DisallowHeapAllocation& promise) {
936 40351509 : Heap* heap = Heap::FromWritableHeapObject(*this);
937 40351509 : if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
938 36111967 : if (Heap::InNewSpace(*this)) return SKIP_WRITE_BARRIER;
939 : return UPDATE_WRITE_BARRIER;
940 : }
941 :
942 117067424 : AllocationAlignment HeapObject::RequiredAlignment(Map map) {
943 : #ifdef V8_HOST_ARCH_32_BIT
944 : int instance_type = map->instance_type();
945 : if (instance_type == FIXED_FLOAT64_ARRAY_TYPE ||
946 : instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
947 : return kDoubleAligned;
948 : }
949 : if (instance_type == HEAP_NUMBER_TYPE) return kDoubleUnaligned;
950 : #endif // V8_HOST_ARCH_32_BIT
951 117067424 : return kWordAligned;
952 : }
953 :
954 377171570 : bool HeapObject::NeedsRehashing() const {
955 377171570 : switch (map()->instance_type()) {
956 : case DESCRIPTOR_ARRAY_TYPE:
957 16347635 : return DescriptorArray::cast(*this)->number_of_descriptors() > 1;
958 : case TRANSITION_ARRAY_TYPE:
959 1288104 : return TransitionArray::cast(*this)->number_of_entries() > 1;
960 : case ORDERED_HASH_MAP_TYPE:
961 63023 : return OrderedHashMap::cast(*this)->NumberOfElements() > 0;
962 : case ORDERED_HASH_SET_TYPE:
963 63018 : return OrderedHashSet::cast(*this)->NumberOfElements() > 0;
964 : case NAME_DICTIONARY_TYPE:
965 : case GLOBAL_DICTIONARY_TYPE:
966 : case NUMBER_DICTIONARY_TYPE:
967 : case SIMPLE_NUMBER_DICTIONARY_TYPE:
968 : case STRING_TABLE_TYPE:
969 : case HASH_TABLE_TYPE:
970 : case SMALL_ORDERED_HASH_MAP_TYPE:
971 : case SMALL_ORDERED_HASH_SET_TYPE:
972 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
973 : return true;
974 : default:
975 359681274 : return false;
976 : }
977 : }
978 :
979 : Address HeapObject::GetFieldAddress(int field_offset) const {
980 57565 : return FIELD_ADDR(this, field_offset);
981 : }
982 :
983 690270 : ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
984 4509 : ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
985 :
986 3415009 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
987 33238 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
988 3448424 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
989 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
990 9806 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
991 604 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
992 456161 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
993 :
994 5704142 : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
995 9843418 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
996 5857417 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
997 :
998 2464897508 : int HeapObject::SizeFromMap(Map map) const {
999 : int instance_size = map->instance_size();
1000 2464897508 : if (instance_size != kVariableSizeSentinel) return instance_size;
1001 : // Only inline the most frequent cases.
1002 : InstanceType instance_type = map->instance_type();
1003 1117558472 : if (IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)) {
1004 : return FixedArray::SizeFor(
1005 168607984 : FixedArray::unchecked_cast(*this)->synchronized_length());
1006 : }
1007 1033257435 : if (IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) {
1008 : // Native context has fixed size.
1009 : DCHECK_NE(instance_type, NATIVE_CONTEXT_TYPE);
1010 9185984 : return Context::SizeFor(Context::unchecked_cast(*this)->length());
1011 : }
1012 2057328892 : if (instance_type == ONE_BYTE_STRING_TYPE ||
1013 1028664446 : instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
1014 : // Strings may get concurrently truncated, hence we have to access its
1015 : // length synchronized.
1016 : return SeqOneByteString::SizeFor(
1017 : SeqOneByteString::unchecked_cast(*this)->synchronized_length());
1018 : }
1019 780965811 : if (instance_type == BYTE_ARRAY_TYPE) {
1020 : return ByteArray::SizeFor(
1021 82896451 : ByteArray::unchecked_cast(*this)->synchronized_length());
1022 : }
1023 739507227 : if (instance_type == BYTECODE_ARRAY_TYPE) {
1024 : return BytecodeArray::SizeFor(
1025 38371542 : BytecodeArray::unchecked_cast(*this)->synchronized_length());
1026 : }
1027 720317059 : if (instance_type == FREE_SPACE_TYPE) {
1028 1130157 : return FreeSpace::unchecked_cast(*this)->relaxed_read_size();
1029 : }
1030 1438373804 : if (instance_type == STRING_TYPE ||
1031 719186902 : instance_type == INTERNALIZED_STRING_TYPE) {
1032 : // Strings may get concurrently truncated, hence we have to access its
1033 : // length synchronized.
1034 : return SeqTwoByteString::SizeFor(
1035 : SeqTwoByteString::unchecked_cast(*this)->synchronized_length());
1036 : }
1037 570388974 : if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
1038 : return FixedDoubleArray::SizeFor(
1039 1005221 : FixedDoubleArray::unchecked_cast(*this)->synchronized_length());
1040 : }
1041 569886341 : if (instance_type == FEEDBACK_METADATA_TYPE) {
1042 : return FeedbackMetadata::SizeFor(
1043 : FeedbackMetadata::unchecked_cast(*this)->synchronized_slot_count());
1044 : }
1045 554224311 : if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
1046 : return DescriptorArray::SizeFor(
1047 82326034 : DescriptorArray::unchecked_cast(*this)->number_of_all_descriptors());
1048 : }
1049 471898277 : if (IsInRange(instance_type, FIRST_WEAK_FIXED_ARRAY_TYPE,
1050 : LAST_WEAK_FIXED_ARRAY_TYPE)) {
1051 : return WeakFixedArray::SizeFor(
1052 24039198 : WeakFixedArray::unchecked_cast(*this)->synchronized_length());
1053 : }
1054 459877467 : if (instance_type == WEAK_ARRAY_LIST_TYPE) {
1055 : return WeakArrayList::SizeForCapacity(
1056 8767679 : WeakArrayList::unchecked_cast(*this)->synchronized_capacity());
1057 : }
1058 455493586 : if (IsInRange(instance_type, FIRST_FIXED_TYPED_ARRAY_TYPE,
1059 : LAST_FIXED_TYPED_ARRAY_TYPE)) {
1060 : return FixedTypedArrayBase::unchecked_cast(*this)->TypedArraySize(
1061 1121320 : instance_type);
1062 : }
1063 454932919 : if (instance_type == SMALL_ORDERED_HASH_SET_TYPE) {
1064 : return SmallOrderedHashSet::SizeFor(
1065 : SmallOrderedHashSet::unchecked_cast(*this)->Capacity());
1066 : }
1067 454932919 : if (instance_type == SMALL_ORDERED_HASH_MAP_TYPE) {
1068 : return SmallOrderedHashMap::SizeFor(
1069 : SmallOrderedHashMap::unchecked_cast(*this)->Capacity());
1070 : }
1071 454932919 : if (instance_type == SMALL_ORDERED_NAME_DICTIONARY_TYPE) {
1072 : return SmallOrderedNameDictionary::SizeFor(
1073 : SmallOrderedNameDictionary::unchecked_cast(*this)->Capacity());
1074 : }
1075 454932919 : if (instance_type == PROPERTY_ARRAY_TYPE) {
1076 : return PropertyArray::SizeFor(
1077 57769280 : PropertyArray::cast(*this)->synchronized_length());
1078 : }
1079 426042848 : if (instance_type == FEEDBACK_VECTOR_TYPE) {
1080 : return FeedbackVector::SizeFor(
1081 : FeedbackVector::unchecked_cast(*this)->length());
1082 : }
1083 408820814 : if (instance_type == BIGINT_TYPE) {
1084 : return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length());
1085 : }
1086 408809644 : if (instance_type == PREPARSE_DATA_TYPE) {
1087 : PreparseData data = PreparseData::unchecked_cast(*this);
1088 : return PreparseData::SizeFor(data->data_length(), data->children_length());
1089 : }
1090 408598618 : if (instance_type == CODE_TYPE) {
1091 816267215 : return Code::unchecked_cast(*this)->CodeSize();
1092 : }
1093 : DCHECK_EQ(instance_type, EMBEDDER_DATA_ARRAY_TYPE);
1094 : return EmbedderDataArray::SizeFor(
1095 883037 : EmbedderDataArray::unchecked_cast(*this)->length());
1096 : }
1097 :
1098 17860 : ACCESSORS(TemplateObjectDescription, raw_strings, FixedArray, kRawStringsOffset)
1099 17860 : ACCESSORS(TemplateObjectDescription, cooked_strings, FixedArray,
1100 : kCookedStringsOffset)
1101 :
1102 : // static
1103 274 : Maybe<bool> Object::GreaterThan(Isolate* isolate, Handle<Object> x,
1104 : Handle<Object> y) {
1105 274 : Maybe<ComparisonResult> result = Compare(isolate, x, y);
1106 274 : if (result.IsJust()) {
1107 274 : switch (result.FromJust()) {
1108 : case ComparisonResult::kGreaterThan:
1109 : return Just(true);
1110 : case ComparisonResult::kLessThan:
1111 : case ComparisonResult::kEqual:
1112 : case ComparisonResult::kUndefined:
1113 : return Just(false);
1114 : }
1115 : }
1116 : return Nothing<bool>();
1117 : }
1118 :
1119 :
1120 : // static
1121 256 : Maybe<bool> Object::GreaterThanOrEqual(Isolate* isolate, Handle<Object> x,
1122 : Handle<Object> y) {
1123 256 : Maybe<ComparisonResult> result = Compare(isolate, x, y);
1124 256 : if (result.IsJust()) {
1125 256 : switch (result.FromJust()) {
1126 : case ComparisonResult::kEqual:
1127 : case ComparisonResult::kGreaterThan:
1128 : return Just(true);
1129 : case ComparisonResult::kLessThan:
1130 : case ComparisonResult::kUndefined:
1131 : return Just(false);
1132 : }
1133 : }
1134 : return Nothing<bool>();
1135 : }
1136 :
1137 :
1138 : // static
1139 292 : Maybe<bool> Object::LessThan(Isolate* isolate, Handle<Object> x,
1140 : Handle<Object> y) {
1141 292 : Maybe<ComparisonResult> result = Compare(isolate, x, y);
1142 292 : if (result.IsJust()) {
1143 274 : switch (result.FromJust()) {
1144 : case ComparisonResult::kLessThan:
1145 : return Just(true);
1146 : case ComparisonResult::kEqual:
1147 : case ComparisonResult::kGreaterThan:
1148 : case ComparisonResult::kUndefined:
1149 : return Just(false);
1150 : }
1151 : }
1152 : return Nothing<bool>();
1153 : }
1154 :
1155 :
1156 : // static
1157 247 : Maybe<bool> Object::LessThanOrEqual(Isolate* isolate, Handle<Object> x,
1158 : Handle<Object> y) {
1159 247 : Maybe<ComparisonResult> result = Compare(isolate, x, y);
1160 247 : if (result.IsJust()) {
1161 247 : switch (result.FromJust()) {
1162 : case ComparisonResult::kEqual:
1163 : case ComparisonResult::kLessThan:
1164 : return Just(true);
1165 : case ComparisonResult::kGreaterThan:
1166 : case ComparisonResult::kUndefined:
1167 : return Just(false);
1168 : }
1169 : }
1170 : return Nothing<bool>();
1171 : }
1172 :
1173 928762 : MaybeHandle<Object> Object::GetPropertyOrElement(Isolate* isolate,
1174 : Handle<Object> object,
1175 : Handle<Name> name) {
1176 928762 : LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
1177 928780 : return GetProperty(&it);
1178 : }
1179 :
1180 1586 : MaybeHandle<Object> Object::SetPropertyOrElement(Isolate* isolate,
1181 : Handle<Object> object,
1182 : Handle<Name> name,
1183 : Handle<Object> value,
1184 : LanguageMode language_mode,
1185 : StoreOrigin store_origin) {
1186 1586 : LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
1187 1586 : MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_origin));
1188 1532 : return value;
1189 : }
1190 :
1191 16207 : MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> receiver,
1192 : Handle<Name> name,
1193 : Handle<JSReceiver> holder) {
1194 : LookupIterator it = LookupIterator::PropertyOrElement(holder->GetIsolate(),
1195 16207 : receiver, name, holder);
1196 16207 : return GetProperty(&it);
1197 : }
1198 :
1199 :
1200 :
1201 : // static
1202 33751035 : Object Object::GetSimpleHash(Object object) {
1203 : DisallowHeapAllocation no_gc;
1204 33751036 : if (object->IsSmi()) {
1205 17537422 : uint32_t hash = ComputeUnseededHash(Smi::ToInt(object));
1206 35074844 : return Smi::FromInt(hash & Smi::kMaxValue);
1207 : }
1208 16213614 : if (object->IsHeapNumber()) {
1209 : double num = HeapNumber::cast(object)->value();
1210 4380 : if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
1211 : // Use ComputeUnseededHash for all values in Signed32 range, including -0,
1212 : // which is considered equal to 0 because collections use SameValueZero.
1213 : uint32_t hash;
1214 : // Check range before conversion to avoid undefined behavior.
1215 6852 : if (num >= kMinInt && num <= kMaxInt && FastI2D(FastD2I(num)) == num) {
1216 519 : hash = ComputeUnseededHash(FastD2I(num));
1217 : } else {
1218 : hash = ComputeLongHash(double_to_uint64(num));
1219 : }
1220 7626 : return Smi::FromInt(hash & Smi::kMaxValue);
1221 : }
1222 16209234 : if (object->IsName()) {
1223 16149165 : uint32_t hash = Name::cast(object)->Hash();
1224 32298332 : return Smi::FromInt(hash);
1225 : }
1226 60069 : if (object->IsOddball()) {
1227 1998 : uint32_t hash = Oddball::cast(object)->to_string()->Hash();
1228 3996 : return Smi::FromInt(hash);
1229 : }
1230 58071 : if (object->IsBigInt()) {
1231 288 : uint32_t hash = BigInt::cast(object)->Hash();
1232 576 : return Smi::FromInt(hash & Smi::kMaxValue);
1233 : }
1234 : DCHECK(object->IsJSReceiver());
1235 57783 : return object;
1236 : }
1237 :
1238 23585273 : Object Object::GetHash() {
1239 : DisallowHeapAllocation no_gc;
1240 23585273 : Object hash = GetSimpleHash(*this);
1241 23585273 : if (hash->IsSmi()) return hash;
1242 :
1243 : DCHECK(IsJSReceiver());
1244 37409 : JSReceiver receiver = JSReceiver::cast(*this);
1245 37409 : return receiver->GetIdentityHash();
1246 : }
1247 :
1248 : Handle<Object> ObjectHashTableShape::AsHandle(Handle<Object> key) {
1249 : return key;
1250 : }
1251 :
1252 13661872 : Relocatable::Relocatable(Isolate* isolate) {
1253 6830936 : isolate_ = isolate;
1254 6830936 : prev_ = isolate->relocatable_top();
1255 : isolate->set_relocatable_top(this);
1256 : }
1257 :
1258 :
1259 6830932 : Relocatable::~Relocatable() {
1260 : DCHECK_EQ(isolate_->relocatable_top(), this);
1261 6830932 : isolate_->set_relocatable_top(prev_);
1262 0 : }
1263 :
1264 : // Predictably converts HeapObject or Address to uint32 by calculating
1265 : // offset of the address in respective MemoryChunk.
1266 : static inline uint32_t ObjectAddressForHashing(Address object) {
1267 13179983 : uint32_t value = static_cast<uint32_t>(object);
1268 13179983 : return value & MemoryChunk::kAlignmentMask;
1269 : }
1270 :
1271 810 : static inline Handle<Object> MakeEntryPair(Isolate* isolate, uint32_t index,
1272 : Handle<Object> value) {
1273 810 : Handle<Object> key = isolate->factory()->Uint32ToString(index);
1274 : Handle<FixedArray> entry_storage =
1275 810 : isolate->factory()->NewUninitializedFixedArray(2);
1276 : {
1277 810 : entry_storage->set(0, *key, SKIP_WRITE_BARRIER);
1278 810 : entry_storage->set(1, *value, SKIP_WRITE_BARRIER);
1279 : }
1280 : return isolate->factory()->NewJSArrayWithElements(entry_storage,
1281 810 : PACKED_ELEMENTS, 2);
1282 : }
1283 :
1284 837 : static inline Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Object> key,
1285 : Handle<Object> value) {
1286 : Handle<FixedArray> entry_storage =
1287 837 : isolate->factory()->NewUninitializedFixedArray(2);
1288 : {
1289 837 : entry_storage->set(0, *key, SKIP_WRITE_BARRIER);
1290 837 : entry_storage->set(1, *value, SKIP_WRITE_BARRIER);
1291 : }
1292 : return isolate->factory()->NewJSArrayWithElements(entry_storage,
1293 837 : PACKED_ELEMENTS, 2);
1294 : }
1295 :
1296 : bool ScopeInfo::IsAsmModule() const {
1297 834784 : return IsAsmModuleField::decode(Flags());
1298 : }
1299 :
1300 : bool ScopeInfo::HasSimpleParameters() const {
1301 63562 : return HasSimpleParametersField::decode(Flags());
1302 : }
1303 :
1304 : #define FIELD_ACCESSORS(name) \
1305 : void ScopeInfo::Set##name(int value) { set(k##name, Smi::FromInt(value)); } \
1306 : int ScopeInfo::name() const { \
1307 : if (length() > 0) { \
1308 : return Smi::ToInt(get(k##name)); \
1309 : } else { \
1310 : return 0; \
1311 : } \
1312 : }
1313 428209494 : FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
1314 : #undef FIELD_ACCESSORS
1315 :
1316 : FreshlyAllocatedBigInt FreshlyAllocatedBigInt::cast(Object object) {
1317 : SLOW_DCHECK(object->IsBigInt());
1318 : return FreshlyAllocatedBigInt(object->ptr());
1319 : }
1320 :
1321 : } // namespace internal
1322 : } // namespace v8
1323 :
1324 : #include "src/objects/object-macros-undef.h"
1325 :
1326 : #endif // V8_OBJECTS_INL_H_
|