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 #ifndef V8_OBJECTS_H_
6 #define V8_OBJECTS_H_
7
8 #include "src/allocation.h"
9 #include "src/assert-scope.h"
10 #include "src/builtins.h"
11 #include "src/elements-kind.h"
12 #include "src/field-index.h"
13 #include "src/flags.h"
14 #include "src/list.h"
15 #include "src/property-details.h"
16 #include "src/smart-pointers.h"
17 #include "src/unicode-inl.h"
18 #if V8_TARGET_ARCH_ARM64
19 #include "src/arm64/constants-arm64.h"
20 #elif V8_TARGET_ARCH_ARM
21 #include "src/arm/constants-arm.h"
22 #elif V8_TARGET_ARCH_MIPS
23 #include "src/mips/constants-mips.h"
24 #endif
25 #include "src/v8checks.h"
26 #include "src/zone.h"
27
28
29 //
30 // Most object types in the V8 JavaScript are described in this file.
31 //
32 // Inheritance hierarchy:
33 // - Object
34 // - Smi (immediate small integer)
35 // - HeapObject (superclass for everything allocated in the heap)
36 // - JSReceiver (suitable for property access)
37 // - JSObject
38 // - JSArray
39 // - JSArrayBuffer
40 // - JSArrayBufferView
41 // - JSTypedArray
42 // - JSDataView
43 // - JSSet
44 // - JSMap
45 // - JSSetIterator
46 // - JSMapIterator
47 // - JSWeakCollection
48 // - JSWeakMap
49 // - JSWeakSet
50 // - JSRegExp
51 // - JSFunction
52 // - JSGeneratorObject
53 // - JSModule
54 // - GlobalObject
55 // - JSGlobalObject
56 // - JSBuiltinsObject
57 // - JSGlobalProxy
58 // - JSValue
59 // - JSDate
60 // - JSMessageObject
61 // - JSProxy
62 // - JSFunctionProxy
63 // - FixedArrayBase
64 // - ByteArray
65 // - FixedArray
66 // - DescriptorArray
67 // - HashTable
68 // - Dictionary
69 // - StringTable
70 // - CompilationCacheTable
71 // - CodeCacheHashTable
72 // - MapCache
73 // - OrderedHashTable
74 // - OrderedHashSet
75 // - OrderedHashMap
76 // - Context
77 // - JSFunctionResultCache
78 // - ScopeInfo
79 // - TransitionArray
80 // - FixedDoubleArray
81 // - ExternalArray
82 // - ExternalUint8ClampedArray
83 // - ExternalInt8Array
84 // - ExternalUint8Array
85 // - ExternalInt16Array
86 // - ExternalUint16Array
87 // - ExternalInt32Array
88 // - ExternalUint32Array
89 // - ExternalFloat32Array
90 // - Name
91 // - String
92 // - SeqString
93 // - SeqOneByteString
94 // - SeqTwoByteString
95 // - SlicedString
96 // - ConsString
97 // - ExternalString
98 // - ExternalAsciiString
99 // - ExternalTwoByteString
100 // - InternalizedString
101 // - SeqInternalizedString
102 // - SeqOneByteInternalizedString
103 // - SeqTwoByteInternalizedString
104 // - ConsInternalizedString
105 // - ExternalInternalizedString
106 // - ExternalAsciiInternalizedString
107 // - ExternalTwoByteInternalizedString
108 // - Symbol
109 // - HeapNumber
110 // - Cell
111 // - PropertyCell
112 // - Code
113 // - Map
114 // - Oddball
115 // - Foreign
116 // - SharedFunctionInfo
117 // - Struct
118 // - Box
119 // - DeclaredAccessorDescriptor
120 // - AccessorInfo
121 // - DeclaredAccessorInfo
122 // - ExecutableAccessorInfo
123 // - AccessorPair
124 // - AccessCheckInfo
125 // - InterceptorInfo
126 // - CallHandlerInfo
127 // - TemplateInfo
128 // - FunctionTemplateInfo
129 // - ObjectTemplateInfo
130 // - Script
131 // - SignatureInfo
132 // - TypeSwitchInfo
133 // - DebugInfo
134 // - BreakPointInfo
135 // - CodeCache
136 //
137 // Formats of Object*:
138 // Smi: [31 bit signed int] 0
139 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
140
141 namespace v8 {
142 namespace internal {
143
144 enum KeyedAccessStoreMode {
145 STANDARD_STORE,
146 STORE_TRANSITION_SMI_TO_OBJECT,
147 STORE_TRANSITION_SMI_TO_DOUBLE,
148 STORE_TRANSITION_DOUBLE_TO_OBJECT,
149 STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
150 STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
151 STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
152 STORE_AND_GROW_NO_TRANSITION,
153 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
154 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
155 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
156 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
157 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
158 STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
159 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
160 STORE_NO_TRANSITION_HANDLE_COW
161 };
162
163
164 enum ContextualMode {
165 NOT_CONTEXTUAL,
166 CONTEXTUAL
167 };
168
169
170 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
171 STANDARD_STORE;
172 STATIC_ASSERT(STANDARD_STORE == 0);
173 STATIC_ASSERT(kGrowICDelta ==
174 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
175 STORE_TRANSITION_SMI_TO_OBJECT);
176 STATIC_ASSERT(kGrowICDelta ==
177 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
178 STORE_TRANSITION_SMI_TO_DOUBLE);
179 STATIC_ASSERT(kGrowICDelta ==
180 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
181 STORE_TRANSITION_DOUBLE_TO_OBJECT);
182
183
GetGrowStoreMode(KeyedAccessStoreMode store_mode)184 static inline KeyedAccessStoreMode GetGrowStoreMode(
185 KeyedAccessStoreMode store_mode) {
186 if (store_mode < STORE_AND_GROW_NO_TRANSITION) {
187 store_mode = static_cast<KeyedAccessStoreMode>(
188 static_cast<int>(store_mode) + kGrowICDelta);
189 }
190 return store_mode;
191 }
192
193
IsTransitionStoreMode(KeyedAccessStoreMode store_mode)194 static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
195 return store_mode > STANDARD_STORE &&
196 store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT &&
197 store_mode != STORE_AND_GROW_NO_TRANSITION;
198 }
199
200
GetNonTransitioningStoreMode(KeyedAccessStoreMode store_mode)201 static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
202 KeyedAccessStoreMode store_mode) {
203 if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
204 return store_mode;
205 }
206 if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
207 return STORE_AND_GROW_NO_TRANSITION;
208 }
209 return STANDARD_STORE;
210 }
211
212
IsGrowStoreMode(KeyedAccessStoreMode store_mode)213 static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
214 return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
215 store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
216 }
217
218
219 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
220 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
221
222
223 // Indicates whether a value can be loaded as a constant.
224 enum StoreMode {
225 ALLOW_AS_CONSTANT,
226 FORCE_FIELD
227 };
228
229
230 // PropertyNormalizationMode is used to specify whether to keep
231 // inobject properties when normalizing properties of a JSObject.
232 enum PropertyNormalizationMode {
233 CLEAR_INOBJECT_PROPERTIES,
234 KEEP_INOBJECT_PROPERTIES
235 };
236
237
238 // NormalizedMapSharingMode is used to specify whether a map may be shared
239 // by different objects with normalized properties.
240 enum NormalizedMapSharingMode {
241 UNIQUE_NORMALIZED_MAP,
242 SHARED_NORMALIZED_MAP
243 };
244
245
246 // Indicates whether transitions can be added to a source map or not.
247 enum TransitionFlag {
248 INSERT_TRANSITION,
249 OMIT_TRANSITION
250 };
251
252
253 enum DebugExtraICState {
254 DEBUG_BREAK,
255 DEBUG_PREPARE_STEP_IN
256 };
257
258
259 // Indicates whether the transition is simple: the target map of the transition
260 // either extends the current map with a new property, or it modifies the
261 // property that was added last to the current map.
262 enum SimpleTransitionFlag {
263 SIMPLE_TRANSITION,
264 FULL_TRANSITION
265 };
266
267
268 // Indicates whether we are only interested in the descriptors of a particular
269 // map, or in all descriptors in the descriptor array.
270 enum DescriptorFlag {
271 ALL_DESCRIPTORS,
272 OWN_DESCRIPTORS
273 };
274
275 // The GC maintains a bit of information, the MarkingParity, which toggles
276 // from odd to even and back every time marking is completed. Incremental
277 // marking can visit an object twice during a marking phase, so algorithms that
278 // that piggy-back on marking can use the parity to ensure that they only
279 // perform an operation on an object once per marking phase: they record the
280 // MarkingParity when they visit an object, and only re-visit the object when it
281 // is marked again and the MarkingParity changes.
282 enum MarkingParity {
283 NO_MARKING_PARITY,
284 ODD_MARKING_PARITY,
285 EVEN_MARKING_PARITY
286 };
287
288 // ICs store extra state in a Code object. The default extra state is
289 // kNoExtraICState.
290 typedef int ExtraICState;
291 static const ExtraICState kNoExtraICState = 0;
292
293 // Instance size sentinel for objects of variable size.
294 const int kVariableSizeSentinel = 0;
295
296 const int kStubMajorKeyBits = 7;
297 const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
298
299 // All Maps have a field instance_type containing a InstanceType.
300 // It describes the type of the instances.
301 //
302 // As an example, a JavaScript object is a heap object and its map
303 // instance_type is JS_OBJECT_TYPE.
304 //
305 // The names of the string instance types are intended to systematically
306 // mirror their encoding in the instance_type field of the map. The default
307 // encoding is considered TWO_BYTE. It is not mentioned in the name. ASCII
308 // encoding is mentioned explicitly in the name. Likewise, the default
309 // representation is considered sequential. It is not mentioned in the
310 // name. The other representations (e.g. CONS, EXTERNAL) are explicitly
311 // mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
312 // string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
313 //
314 // NOTE: The following things are some that depend on the string types having
315 // instance_types that are less than those of all other types:
316 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
317 // Object::IsString.
318 //
319 // NOTE: Everything following JS_VALUE_TYPE is considered a
320 // JSObject for GC purposes. The first four entries here have typeof
321 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
322 #define INSTANCE_TYPE_LIST(V) \
323 V(STRING_TYPE) \
324 V(ASCII_STRING_TYPE) \
325 V(CONS_STRING_TYPE) \
326 V(CONS_ASCII_STRING_TYPE) \
327 V(SLICED_STRING_TYPE) \
328 V(SLICED_ASCII_STRING_TYPE) \
329 V(EXTERNAL_STRING_TYPE) \
330 V(EXTERNAL_ASCII_STRING_TYPE) \
331 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
332 V(SHORT_EXTERNAL_STRING_TYPE) \
333 V(SHORT_EXTERNAL_ASCII_STRING_TYPE) \
334 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
335 \
336 V(INTERNALIZED_STRING_TYPE) \
337 V(ASCII_INTERNALIZED_STRING_TYPE) \
338 V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
339 V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE) \
340 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
341 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
342 V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE) \
343 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
344 \
345 V(SYMBOL_TYPE) \
346 \
347 V(MAP_TYPE) \
348 V(CODE_TYPE) \
349 V(ODDBALL_TYPE) \
350 V(CELL_TYPE) \
351 V(PROPERTY_CELL_TYPE) \
352 \
353 V(HEAP_NUMBER_TYPE) \
354 V(FOREIGN_TYPE) \
355 V(BYTE_ARRAY_TYPE) \
356 V(FREE_SPACE_TYPE) \
357 /* Note: the order of these external array */ \
358 /* types is relied upon in */ \
359 /* Object::IsExternalArray(). */ \
360 V(EXTERNAL_INT8_ARRAY_TYPE) \
361 V(EXTERNAL_UINT8_ARRAY_TYPE) \
362 V(EXTERNAL_INT16_ARRAY_TYPE) \
363 V(EXTERNAL_UINT16_ARRAY_TYPE) \
364 V(EXTERNAL_INT32_ARRAY_TYPE) \
365 V(EXTERNAL_UINT32_ARRAY_TYPE) \
366 V(EXTERNAL_FLOAT32_ARRAY_TYPE) \
367 V(EXTERNAL_FLOAT64_ARRAY_TYPE) \
368 V(EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE) \
369 \
370 V(FIXED_INT8_ARRAY_TYPE) \
371 V(FIXED_UINT8_ARRAY_TYPE) \
372 V(FIXED_INT16_ARRAY_TYPE) \
373 V(FIXED_UINT16_ARRAY_TYPE) \
374 V(FIXED_INT32_ARRAY_TYPE) \
375 V(FIXED_UINT32_ARRAY_TYPE) \
376 V(FIXED_FLOAT32_ARRAY_TYPE) \
377 V(FIXED_FLOAT64_ARRAY_TYPE) \
378 V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
379 \
380 V(FILLER_TYPE) \
381 \
382 V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE) \
383 V(DECLARED_ACCESSOR_INFO_TYPE) \
384 V(EXECUTABLE_ACCESSOR_INFO_TYPE) \
385 V(ACCESSOR_PAIR_TYPE) \
386 V(ACCESS_CHECK_INFO_TYPE) \
387 V(INTERCEPTOR_INFO_TYPE) \
388 V(CALL_HANDLER_INFO_TYPE) \
389 V(FUNCTION_TEMPLATE_INFO_TYPE) \
390 V(OBJECT_TEMPLATE_INFO_TYPE) \
391 V(SIGNATURE_INFO_TYPE) \
392 V(TYPE_SWITCH_INFO_TYPE) \
393 V(ALLOCATION_MEMENTO_TYPE) \
394 V(ALLOCATION_SITE_TYPE) \
395 V(SCRIPT_TYPE) \
396 V(CODE_CACHE_TYPE) \
397 V(POLYMORPHIC_CODE_CACHE_TYPE) \
398 V(TYPE_FEEDBACK_INFO_TYPE) \
399 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
400 V(BOX_TYPE) \
401 \
402 V(FIXED_ARRAY_TYPE) \
403 V(FIXED_DOUBLE_ARRAY_TYPE) \
404 V(CONSTANT_POOL_ARRAY_TYPE) \
405 V(SHARED_FUNCTION_INFO_TYPE) \
406 \
407 V(JS_MESSAGE_OBJECT_TYPE) \
408 \
409 V(JS_VALUE_TYPE) \
410 V(JS_DATE_TYPE) \
411 V(JS_OBJECT_TYPE) \
412 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
413 V(JS_GENERATOR_OBJECT_TYPE) \
414 V(JS_MODULE_TYPE) \
415 V(JS_GLOBAL_OBJECT_TYPE) \
416 V(JS_BUILTINS_OBJECT_TYPE) \
417 V(JS_GLOBAL_PROXY_TYPE) \
418 V(JS_ARRAY_TYPE) \
419 V(JS_ARRAY_BUFFER_TYPE) \
420 V(JS_TYPED_ARRAY_TYPE) \
421 V(JS_DATA_VIEW_TYPE) \
422 V(JS_PROXY_TYPE) \
423 V(JS_SET_TYPE) \
424 V(JS_MAP_TYPE) \
425 V(JS_SET_ITERATOR_TYPE) \
426 V(JS_MAP_ITERATOR_TYPE) \
427 V(JS_WEAK_MAP_TYPE) \
428 V(JS_WEAK_SET_TYPE) \
429 V(JS_REGEXP_TYPE) \
430 \
431 V(JS_FUNCTION_TYPE) \
432 V(JS_FUNCTION_PROXY_TYPE) \
433 V(DEBUG_INFO_TYPE) \
434 V(BREAK_POINT_INFO_TYPE)
435
436
437 // Since string types are not consecutive, this macro is used to
438 // iterate over them.
439 #define STRING_TYPE_LIST(V) \
440 V(STRING_TYPE, \
441 kVariableSizeSentinel, \
442 string, \
443 String) \
444 V(ASCII_STRING_TYPE, \
445 kVariableSizeSentinel, \
446 ascii_string, \
447 AsciiString) \
448 V(CONS_STRING_TYPE, \
449 ConsString::kSize, \
450 cons_string, \
451 ConsString) \
452 V(CONS_ASCII_STRING_TYPE, \
453 ConsString::kSize, \
454 cons_ascii_string, \
455 ConsAsciiString) \
456 V(SLICED_STRING_TYPE, \
457 SlicedString::kSize, \
458 sliced_string, \
459 SlicedString) \
460 V(SLICED_ASCII_STRING_TYPE, \
461 SlicedString::kSize, \
462 sliced_ascii_string, \
463 SlicedAsciiString) \
464 V(EXTERNAL_STRING_TYPE, \
465 ExternalTwoByteString::kSize, \
466 external_string, \
467 ExternalString) \
468 V(EXTERNAL_ASCII_STRING_TYPE, \
469 ExternalAsciiString::kSize, \
470 external_ascii_string, \
471 ExternalAsciiString) \
472 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
473 ExternalTwoByteString::kSize, \
474 external_string_with_one_byte_data, \
475 ExternalStringWithOneByteData) \
476 V(SHORT_EXTERNAL_STRING_TYPE, \
477 ExternalTwoByteString::kShortSize, \
478 short_external_string, \
479 ShortExternalString) \
480 V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \
481 ExternalAsciiString::kShortSize, \
482 short_external_ascii_string, \
483 ShortExternalAsciiString) \
484 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
485 ExternalTwoByteString::kShortSize, \
486 short_external_string_with_one_byte_data, \
487 ShortExternalStringWithOneByteData) \
488 \
489 V(INTERNALIZED_STRING_TYPE, \
490 kVariableSizeSentinel, \
491 internalized_string, \
492 InternalizedString) \
493 V(ASCII_INTERNALIZED_STRING_TYPE, \
494 kVariableSizeSentinel, \
495 ascii_internalized_string, \
496 AsciiInternalizedString) \
497 V(EXTERNAL_INTERNALIZED_STRING_TYPE, \
498 ExternalTwoByteString::kSize, \
499 external_internalized_string, \
500 ExternalInternalizedString) \
501 V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE, \
502 ExternalAsciiString::kSize, \
503 external_ascii_internalized_string, \
504 ExternalAsciiInternalizedString) \
505 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
506 ExternalTwoByteString::kSize, \
507 external_internalized_string_with_one_byte_data, \
508 ExternalInternalizedStringWithOneByteData) \
509 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE, \
510 ExternalTwoByteString::kShortSize, \
511 short_external_internalized_string, \
512 ShortExternalInternalizedString) \
513 V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE, \
514 ExternalAsciiString::kShortSize, \
515 short_external_ascii_internalized_string, \
516 ShortExternalAsciiInternalizedString) \
517 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
518 ExternalTwoByteString::kShortSize, \
519 short_external_internalized_string_with_one_byte_data, \
520 ShortExternalInternalizedStringWithOneByteData) \
521
522 // A struct is a simple object a set of object-valued fields. Including an
523 // object type in this causes the compiler to generate most of the boilerplate
524 // code for the class including allocation and garbage collection routines,
525 // casts and predicates. All you need to define is the class, methods and
526 // object verification routines. Easy, no?
527 //
528 // Note that for subtle reasons related to the ordering or numerical values of
529 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
530 // manually.
531 #define STRUCT_LIST(V) \
532 V(BOX, Box, box) \
533 V(DECLARED_ACCESSOR_DESCRIPTOR, \
534 DeclaredAccessorDescriptor, \
535 declared_accessor_descriptor) \
536 V(DECLARED_ACCESSOR_INFO, DeclaredAccessorInfo, declared_accessor_info) \
537 V(EXECUTABLE_ACCESSOR_INFO, ExecutableAccessorInfo, executable_accessor_info)\
538 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
539 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
540 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
541 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
542 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
543 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
544 V(SIGNATURE_INFO, SignatureInfo, signature_info) \
545 V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \
546 V(SCRIPT, Script, script) \
547 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
548 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
549 V(CODE_CACHE, CodeCache, code_cache) \
550 V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
551 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
552 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
553 V(DEBUG_INFO, DebugInfo, debug_info) \
554 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
555
556 // We use the full 8 bits of the instance_type field to encode heap object
557 // instance types. The high-order bit (bit 7) is set if the object is not a
558 // string, and cleared if it is a string.
559 const uint32_t kIsNotStringMask = 0x80;
560 const uint32_t kStringTag = 0x0;
561 const uint32_t kNotStringTag = 0x80;
562
563 // Bit 6 indicates that the object is an internalized string (if set) or not.
564 // Bit 7 has to be clear as well.
565 const uint32_t kIsNotInternalizedMask = 0x40;
566 const uint32_t kNotInternalizedTag = 0x40;
567 const uint32_t kInternalizedTag = 0x0;
568
569 // If bit 7 is clear then bit 2 indicates whether the string consists of
570 // two-byte characters or one-byte characters.
571 const uint32_t kStringEncodingMask = 0x4;
572 const uint32_t kTwoByteStringTag = 0x0;
573 const uint32_t kOneByteStringTag = 0x4;
574
575 // If bit 7 is clear, the low-order 2 bits indicate the representation
576 // of the string.
577 const uint32_t kStringRepresentationMask = 0x03;
578 enum StringRepresentationTag {
579 kSeqStringTag = 0x0,
580 kConsStringTag = 0x1,
581 kExternalStringTag = 0x2,
582 kSlicedStringTag = 0x3
583 };
584 const uint32_t kIsIndirectStringMask = 0x1;
585 const uint32_t kIsIndirectStringTag = 0x1;
586 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
587 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
588 STATIC_ASSERT((kConsStringTag &
589 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
590 STATIC_ASSERT((kSlicedStringTag &
591 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
592
593 // Use this mask to distinguish between cons and slice only after making
594 // sure that the string is one of the two (an indirect string).
595 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
596 STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
597
598 // If bit 7 is clear, then bit 3 indicates whether this two-byte
599 // string actually contains one byte data.
600 const uint32_t kOneByteDataHintMask = 0x08;
601 const uint32_t kOneByteDataHintTag = 0x08;
602
603 // If bit 7 is clear and string representation indicates an external string,
604 // then bit 4 indicates whether the data pointer is cached.
605 const uint32_t kShortExternalStringMask = 0x10;
606 const uint32_t kShortExternalStringTag = 0x10;
607
608
609 // A ConsString with an empty string as the right side is a candidate
610 // for being shortcut by the garbage collector unless it is internalized.
611 // It's not common to have non-flat internalized strings, so we do not
612 // shortcut them thereby avoiding turning internalized strings into strings.
613 // See heap.cc and mark-compact.cc.
614 const uint32_t kShortcutTypeMask =
615 kIsNotStringMask |
616 kIsNotInternalizedMask |
617 kStringRepresentationMask;
618 const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
619
620
621 enum InstanceType {
622 // String types.
623 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag
624 | kInternalizedTag,
625 ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag
626 | kInternalizedTag,
627 EXTERNAL_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kExternalStringTag
628 | kInternalizedTag,
629 EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag
630 | kExternalStringTag | kInternalizedTag,
631 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
632 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag
633 | kInternalizedTag,
634 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE =
635 EXTERNAL_INTERNALIZED_STRING_TYPE | kShortExternalStringTag
636 | kInternalizedTag,
637 SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE =
638 EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kShortExternalStringTag
639 | kInternalizedTag,
640 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
641 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
642 | kShortExternalStringTag | kInternalizedTag,
643
644 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
645 ASCII_STRING_TYPE = ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
646 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
647 CONS_ASCII_STRING_TYPE =
648 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
649
650 SLICED_STRING_TYPE =
651 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
652 SLICED_ASCII_STRING_TYPE =
653 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
654 EXTERNAL_STRING_TYPE =
655 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
656 EXTERNAL_ASCII_STRING_TYPE =
657 EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
658 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
659 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
660 | kNotInternalizedTag,
661 SHORT_EXTERNAL_STRING_TYPE =
662 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
663 SHORT_EXTERNAL_ASCII_STRING_TYPE =
664 SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
665 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
666 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
667 | kNotInternalizedTag,
668
669 // Non-string names
670 SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
671
672 // Objects allocated in their own spaces (never in new space).
673 MAP_TYPE,
674 CODE_TYPE,
675 ODDBALL_TYPE,
676 CELL_TYPE,
677 PROPERTY_CELL_TYPE,
678
679 // "Data", objects that cannot contain non-map-word pointers to heap
680 // objects.
681 HEAP_NUMBER_TYPE,
682 FOREIGN_TYPE,
683 BYTE_ARRAY_TYPE,
684 FREE_SPACE_TYPE,
685
686 EXTERNAL_INT8_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE
687 EXTERNAL_UINT8_ARRAY_TYPE,
688 EXTERNAL_INT16_ARRAY_TYPE,
689 EXTERNAL_UINT16_ARRAY_TYPE,
690 EXTERNAL_INT32_ARRAY_TYPE,
691 EXTERNAL_UINT32_ARRAY_TYPE,
692 EXTERNAL_FLOAT32_ARRAY_TYPE,
693 EXTERNAL_FLOAT64_ARRAY_TYPE,
694 EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE
695
696 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
697 FIXED_UINT8_ARRAY_TYPE,
698 FIXED_INT16_ARRAY_TYPE,
699 FIXED_UINT16_ARRAY_TYPE,
700 FIXED_INT32_ARRAY_TYPE,
701 FIXED_UINT32_ARRAY_TYPE,
702 FIXED_FLOAT32_ARRAY_TYPE,
703 FIXED_FLOAT64_ARRAY_TYPE,
704 FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
705
706 FIXED_DOUBLE_ARRAY_TYPE,
707 FILLER_TYPE, // LAST_DATA_TYPE
708
709 // Structs.
710 DECLARED_ACCESSOR_DESCRIPTOR_TYPE,
711 DECLARED_ACCESSOR_INFO_TYPE,
712 EXECUTABLE_ACCESSOR_INFO_TYPE,
713 ACCESSOR_PAIR_TYPE,
714 ACCESS_CHECK_INFO_TYPE,
715 INTERCEPTOR_INFO_TYPE,
716 CALL_HANDLER_INFO_TYPE,
717 FUNCTION_TEMPLATE_INFO_TYPE,
718 OBJECT_TEMPLATE_INFO_TYPE,
719 SIGNATURE_INFO_TYPE,
720 TYPE_SWITCH_INFO_TYPE,
721 ALLOCATION_SITE_TYPE,
722 ALLOCATION_MEMENTO_TYPE,
723 SCRIPT_TYPE,
724 CODE_CACHE_TYPE,
725 POLYMORPHIC_CODE_CACHE_TYPE,
726 TYPE_FEEDBACK_INFO_TYPE,
727 ALIASED_ARGUMENTS_ENTRY_TYPE,
728 BOX_TYPE,
729 DEBUG_INFO_TYPE,
730 BREAK_POINT_INFO_TYPE,
731
732 FIXED_ARRAY_TYPE,
733 CONSTANT_POOL_ARRAY_TYPE,
734 SHARED_FUNCTION_INFO_TYPE,
735
736 // All the following types are subtypes of JSReceiver, which corresponds to
737 // objects in the JS sense. The first and the last type in this range are
738 // the two forms of function. This organization enables using the same
739 // compares for checking the JS_RECEIVER/SPEC_OBJECT range and the
740 // NONCALLABLE_JS_OBJECT range.
741 JS_FUNCTION_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE, FIRST_JS_PROXY_TYPE
742 JS_PROXY_TYPE, // LAST_JS_PROXY_TYPE
743
744 JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE
745 JS_MESSAGE_OBJECT_TYPE,
746 JS_DATE_TYPE,
747 JS_OBJECT_TYPE,
748 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
749 JS_GENERATOR_OBJECT_TYPE,
750 JS_MODULE_TYPE,
751 JS_GLOBAL_OBJECT_TYPE,
752 JS_BUILTINS_OBJECT_TYPE,
753 JS_GLOBAL_PROXY_TYPE,
754 JS_ARRAY_TYPE,
755 JS_ARRAY_BUFFER_TYPE,
756 JS_TYPED_ARRAY_TYPE,
757 JS_DATA_VIEW_TYPE,
758 JS_SET_TYPE,
759 JS_MAP_TYPE,
760 JS_SET_ITERATOR_TYPE,
761 JS_MAP_ITERATOR_TYPE,
762 JS_WEAK_MAP_TYPE,
763 JS_WEAK_SET_TYPE,
764
765 JS_REGEXP_TYPE,
766
767 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
768
769 // Pseudo-types
770 FIRST_TYPE = 0x0,
771 LAST_TYPE = JS_FUNCTION_TYPE,
772 FIRST_NAME_TYPE = FIRST_TYPE,
773 LAST_NAME_TYPE = SYMBOL_TYPE,
774 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
775 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
776 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
777 // Boundaries for testing for an external array.
778 FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_INT8_ARRAY_TYPE,
779 LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE,
780 // Boundaries for testing for a fixed typed array.
781 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
782 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
783 // Boundary for promotion to old data space/old pointer space.
784 LAST_DATA_TYPE = FILLER_TYPE,
785 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
786 // Note that there is no range for JSObject or JSProxy, since their subtypes
787 // are not continuous in this enum! The enum ranges instead reflect the
788 // external class names, where proxies are treated as either ordinary objects,
789 // or functions.
790 FIRST_JS_RECEIVER_TYPE = JS_FUNCTION_PROXY_TYPE,
791 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
792 // Boundaries for testing the types represented as JSObject
793 FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
794 LAST_JS_OBJECT_TYPE = LAST_TYPE,
795 // Boundaries for testing the types represented as JSProxy
796 FIRST_JS_PROXY_TYPE = JS_FUNCTION_PROXY_TYPE,
797 LAST_JS_PROXY_TYPE = JS_PROXY_TYPE,
798 // Boundaries for testing whether the type is a JavaScript object.
799 FIRST_SPEC_OBJECT_TYPE = FIRST_JS_RECEIVER_TYPE,
800 LAST_SPEC_OBJECT_TYPE = LAST_JS_RECEIVER_TYPE,
801 // Boundaries for testing the types for which typeof is "object".
802 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_PROXY_TYPE,
803 LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
804 // Note that the types for which typeof is "function" are not continuous.
805 // Define this so that we can put assertions on discrete checks.
806 NUM_OF_CALLABLE_SPEC_OBJECT_TYPES = 2
807 };
808
809 const int kExternalArrayTypeCount =
810 LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1;
811
812 STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
813 STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
814 STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
815 STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
816
817
818 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
819 V(FAST_ELEMENTS_SUB_TYPE) \
820 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
821 V(FAST_PROPERTIES_SUB_TYPE) \
822 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
823 V(MAP_CODE_CACHE_SUB_TYPE) \
824 V(SCOPE_INFO_SUB_TYPE) \
825 V(STRING_TABLE_SUB_TYPE) \
826 V(DESCRIPTOR_ARRAY_SUB_TYPE) \
827 V(TRANSITION_ARRAY_SUB_TYPE)
828
829 enum FixedArraySubInstanceType {
830 #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
831 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
832 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
833 LAST_FIXED_ARRAY_SUB_TYPE = TRANSITION_ARRAY_SUB_TYPE
834 };
835
836
837 enum CompareResult {
838 LESS = -1,
839 EQUAL = 0,
840 GREATER = 1,
841
842 NOT_EQUAL = GREATER
843 };
844
845
846 #define DECL_BOOLEAN_ACCESSORS(name) \
847 inline bool name(); \
848 inline void set_##name(bool value); \
849
850
851 #define DECL_ACCESSORS(name, type) \
852 inline type* name(); \
853 inline void set_##name(type* value, \
854 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
855
856 class AccessorPair;
857 class AllocationSite;
858 class AllocationSiteCreationContext;
859 class AllocationSiteUsageContext;
860 class DictionaryElementsAccessor;
861 class ElementsAccessor;
862 class FixedArrayBase;
863 class GlobalObject;
864 class ObjectVisitor;
865 class LookupIterator;
866 class StringStream;
867 // We cannot just say "class HeapType;" if it is created from a template... =8-?
868 template<class> class TypeImpl;
869 struct HeapTypeConfig;
870 typedef TypeImpl<HeapTypeConfig> HeapType;
871
872
873 // A template-ized version of the IsXXX functions.
874 template <class C> inline bool Is(Object* obj);
875
876 #ifdef VERIFY_HEAP
877 #define DECLARE_VERIFIER(Name) void Name##Verify();
878 #else
879 #define DECLARE_VERIFIER(Name)
880 #endif
881
882 #ifdef OBJECT_PRINT
883 #define DECLARE_PRINTER(Name) void Name##Print(FILE* out = stdout);
884 #else
885 #define DECLARE_PRINTER(Name)
886 #endif
887
888
889 #define OBJECT_TYPE_LIST(V) \
890 V(Smi) \
891 V(HeapObject) \
892 V(Number) \
893
894 #define HEAP_OBJECT_TYPE_LIST(V) \
895 V(HeapNumber) \
896 V(Name) \
897 V(UniqueName) \
898 V(String) \
899 V(SeqString) \
900 V(ExternalString) \
901 V(ConsString) \
902 V(SlicedString) \
903 V(ExternalTwoByteString) \
904 V(ExternalAsciiString) \
905 V(SeqTwoByteString) \
906 V(SeqOneByteString) \
907 V(InternalizedString) \
908 V(Symbol) \
909 \
910 V(ExternalArray) \
911 V(ExternalInt8Array) \
912 V(ExternalUint8Array) \
913 V(ExternalInt16Array) \
914 V(ExternalUint16Array) \
915 V(ExternalInt32Array) \
916 V(ExternalUint32Array) \
917 V(ExternalFloat32Array) \
918 V(ExternalFloat64Array) \
919 V(ExternalUint8ClampedArray) \
920 V(FixedTypedArrayBase) \
921 V(FixedUint8Array) \
922 V(FixedInt8Array) \
923 V(FixedUint16Array) \
924 V(FixedInt16Array) \
925 V(FixedUint32Array) \
926 V(FixedInt32Array) \
927 V(FixedFloat32Array) \
928 V(FixedFloat64Array) \
929 V(FixedUint8ClampedArray) \
930 V(ByteArray) \
931 V(FreeSpace) \
932 V(JSReceiver) \
933 V(JSObject) \
934 V(JSContextExtensionObject) \
935 V(JSGeneratorObject) \
936 V(JSModule) \
937 V(Map) \
938 V(DescriptorArray) \
939 V(TransitionArray) \
940 V(DeoptimizationInputData) \
941 V(DeoptimizationOutputData) \
942 V(DependentCode) \
943 V(FixedArray) \
944 V(FixedDoubleArray) \
945 V(ConstantPoolArray) \
946 V(Context) \
947 V(NativeContext) \
948 V(ScopeInfo) \
949 V(JSFunction) \
950 V(Code) \
951 V(Oddball) \
952 V(SharedFunctionInfo) \
953 V(JSValue) \
954 V(JSDate) \
955 V(JSMessageObject) \
956 V(StringWrapper) \
957 V(Foreign) \
958 V(Boolean) \
959 V(JSArray) \
960 V(JSArrayBuffer) \
961 V(JSArrayBufferView) \
962 V(JSTypedArray) \
963 V(JSDataView) \
964 V(JSProxy) \
965 V(JSFunctionProxy) \
966 V(JSSet) \
967 V(JSMap) \
968 V(JSSetIterator) \
969 V(JSMapIterator) \
970 V(JSWeakCollection) \
971 V(JSWeakMap) \
972 V(JSWeakSet) \
973 V(JSRegExp) \
974 V(HashTable) \
975 V(Dictionary) \
976 V(StringTable) \
977 V(JSFunctionResultCache) \
978 V(NormalizedMapCache) \
979 V(CompilationCacheTable) \
980 V(CodeCacheHashTable) \
981 V(PolymorphicCodeCacheHashTable) \
982 V(MapCache) \
983 V(Primitive) \
984 V(GlobalObject) \
985 V(JSGlobalObject) \
986 V(JSBuiltinsObject) \
987 V(JSGlobalProxy) \
988 V(UndetectableObject) \
989 V(AccessCheckNeeded) \
990 V(Cell) \
991 V(PropertyCell) \
992 V(ObjectHashTable) \
993 V(WeakHashTable) \
994 V(OrderedHashTable)
995
996
997 #define ERROR_MESSAGES_LIST(V) \
998 V(kNoReason, "no reason") \
999 \
1000 V(k32BitValueInRegisterIsNotZeroExtended, \
1001 "32 bit value in register is not zero-extended") \
1002 V(kAlignmentMarkerExpected, "Alignment marker expected") \
1003 V(kAllocationIsNotDoubleAligned, "Allocation is not double aligned") \
1004 V(kAPICallReturnedInvalidObject, "API call returned invalid object") \
1005 V(kArgumentsObjectValueInATestContext, \
1006 "Arguments object value in a test context") \
1007 V(kArrayBoilerplateCreationFailed, "Array boilerplate creation failed") \
1008 V(kArrayIndexConstantValueTooBig, "Array index constant value too big") \
1009 V(kAssignmentToArguments, "Assignment to arguments") \
1010 V(kAssignmentToLetVariableBeforeInitialization, \
1011 "Assignment to let variable before initialization") \
1012 V(kAssignmentToLOOKUPVariable, "Assignment to LOOKUP variable") \
1013 V(kAssignmentToParameterFunctionUsesArgumentsObject, \
1014 "Assignment to parameter, function uses arguments object") \
1015 V(kAssignmentToParameterInArgumentsObject, \
1016 "Assignment to parameter in arguments object") \
1017 V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache") \
1018 V(kBadValueContextForArgumentsObjectValue, \
1019 "Bad value context for arguments object value") \
1020 V(kBadValueContextForArgumentsValue, \
1021 "Bad value context for arguments value") \
1022 V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
1023 V(kBailoutWasNotPrepared, "Bailout was not prepared") \
1024 V(kBinaryStubGenerateFloatingPointCode, \
1025 "BinaryStub_GenerateFloatingPointCode") \
1026 V(kBothRegistersWereSmisInSelectNonSmi, \
1027 "Both registers were smis in SelectNonSmi") \
1028 V(kCallToAJavaScriptRuntimeFunction, \
1029 "Call to a JavaScript runtime function") \
1030 V(kCannotTranslatePositionInChangedArea, \
1031 "Cannot translate position in changed area") \
1032 V(kCodeGenerationFailed, "Code generation failed") \
1033 V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \
1034 V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \
1035 V(kContextAllocatedArguments, "Context-allocated arguments") \
1036 V(kCopyBuffersOverlap, "Copy buffers overlap") \
1037 V(kCouldNotGenerateZero, "Could not generate +0.0") \
1038 V(kCouldNotGenerateNegativeZero, "Could not generate -0.0") \
1039 V(kDebuggerHasBreakPoints, "Debugger has break points") \
1040 V(kDebuggerStatement, "DebuggerStatement") \
1041 V(kDeclarationInCatchContext, "Declaration in catch context") \
1042 V(kDeclarationInWithContext, "Declaration in with context") \
1043 V(kDefaultNaNModeNotSet, "Default NaN mode not set") \
1044 V(kDeleteWithGlobalVariable, "Delete with global variable") \
1045 V(kDeleteWithNonGlobalVariable, "Delete with non-global variable") \
1046 V(kDestinationOfCopyNotAligned, "Destination of copy not aligned") \
1047 V(kDontDeleteCellsCannotContainTheHole, \
1048 "DontDelete cells can't contain the hole") \
1049 V(kDoPushArgumentNotImplementedForDoubleType, \
1050 "DoPushArgument not implemented for double type") \
1051 V(kEliminatedBoundsCheckFailed, "Eliminated bounds check failed") \
1052 V(kEmitLoadRegisterUnsupportedDoubleImmediate, \
1053 "EmitLoadRegister: Unsupported double immediate") \
1054 V(kEval, "eval") \
1055 V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel") \
1056 V(kExpectedAlignmentMarker, "Expected alignment marker") \
1057 V(kExpectedAllocationSite, "Expected allocation site") \
1058 V(kExpectedFunctionObject, "Expected function object in register") \
1059 V(kExpectedHeapNumber, "Expected HeapNumber") \
1060 V(kExpectedNativeContext, "Expected native context") \
1061 V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \
1062 V(kExpectedNonNullContext, "Expected non-null context") \
1063 V(kExpectedPositiveZero, "Expected +0.0") \
1064 V(kExpectedAllocationSiteInCell, \
1065 "Expected AllocationSite in property cell") \
1066 V(kExpectedFixedArrayInFeedbackVector, \
1067 "Expected fixed array in feedback vector") \
1068 V(kExpectedFixedArrayInRegisterA2, \
1069 "Expected fixed array in register a2") \
1070 V(kExpectedFixedArrayInRegisterEbx, \
1071 "Expected fixed array in register ebx") \
1072 V(kExpectedFixedArrayInRegisterR2, \
1073 "Expected fixed array in register r2") \
1074 V(kExpectedFixedArrayInRegisterRbx, \
1075 "Expected fixed array in register rbx") \
1076 V(kExpectedNewSpaceObject, "Expected new space object") \
1077 V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \
1078 V(kExpectedUndefinedOrCell, \
1079 "Expected undefined or cell in register") \
1080 V(kExpectingAlignmentForCopyBytes, \
1081 "Expecting alignment for CopyBytes") \
1082 V(kExportDeclaration, "Export declaration") \
1083 V(kExternalStringExpectedButNotFound, \
1084 "External string expected, but not found") \
1085 V(kFailedBailedOutLastTime, "Failed/bailed out last time") \
1086 V(kForInStatementIsNotFastCase, "ForInStatement is not fast case") \
1087 V(kForInStatementOptimizationIsDisabled, \
1088 "ForInStatement optimization is disabled") \
1089 V(kForInStatementWithNonLocalEachVariable, \
1090 "ForInStatement with non-local each variable") \
1091 V(kForOfStatement, "ForOfStatement") \
1092 V(kFrameIsExpectedToBeAligned, "Frame is expected to be aligned") \
1093 V(kFunctionCallsEval, "Function calls eval") \
1094 V(kFunctionIsAGenerator, "Function is a generator") \
1095 V(kFunctionWithIllegalRedeclaration, "Function with illegal redeclaration") \
1096 V(kGeneratedCodeIsTooLarge, "Generated code is too large") \
1097 V(kGeneratorFailedToResume, "Generator failed to resume") \
1098 V(kGenerator, "Generator") \
1099 V(kGlobalFunctionsMustHaveInitialMap, \
1100 "Global functions must have initial map") \
1101 V(kHeapNumberMapRegisterClobbered, "HeapNumberMap register clobbered") \
1102 V(kHydrogenFilter, "Optimization disabled by filter") \
1103 V(kImportDeclaration, "Import declaration") \
1104 V(kImproperObjectOnPrototypeChainForStore, \
1105 "Improper object on prototype chain for store") \
1106 V(kIndexIsNegative, "Index is negative") \
1107 V(kIndexIsTooLarge, "Index is too large") \
1108 V(kInlinedRuntimeFunctionClassOf, "Inlined runtime function: ClassOf") \
1109 V(kInlinedRuntimeFunctionFastAsciiArrayJoin, \
1110 "Inlined runtime function: FastAsciiArrayJoin") \
1111 V(kInlinedRuntimeFunctionGeneratorNext, \
1112 "Inlined runtime function: GeneratorNext") \
1113 V(kInlinedRuntimeFunctionGeneratorThrow, \
1114 "Inlined runtime function: GeneratorThrow") \
1115 V(kInlinedRuntimeFunctionGetFromCache, \
1116 "Inlined runtime function: GetFromCache") \
1117 V(kInlinedRuntimeFunctionIsNonNegativeSmi, \
1118 "Inlined runtime function: IsNonNegativeSmi") \
1119 V(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf, \
1120 "Inlined runtime function: IsStringWrapperSafeForDefaultValueOf") \
1121 V(kInliningBailedOut, "Inlining bailed out") \
1122 V(kInputGPRIsExpectedToHaveUpper32Cleared, \
1123 "Input GPR is expected to have upper32 cleared") \
1124 V(kInputStringTooLong, "Input string too long") \
1125 V(kInstanceofStubUnexpectedCallSiteCacheCheck, \
1126 "InstanceofStub unexpected call site cache (check)") \
1127 V(kInstanceofStubUnexpectedCallSiteCacheCmp1, \
1128 "InstanceofStub unexpected call site cache (cmp 1)") \
1129 V(kInstanceofStubUnexpectedCallSiteCacheCmp2, \
1130 "InstanceofStub unexpected call site cache (cmp 2)") \
1131 V(kInstanceofStubUnexpectedCallSiteCacheMov, \
1132 "InstanceofStub unexpected call site cache (mov)") \
1133 V(kInteger32ToSmiFieldWritingToNonSmiLocation, \
1134 "Integer32ToSmiField writing to non-smi location") \
1135 V(kInvalidCaptureReferenced, "Invalid capture referenced") \
1136 V(kInvalidElementsKindForInternalArrayOrInternalPackedArray, \
1137 "Invalid ElementsKind for InternalArray or InternalPackedArray") \
1138 V(kInvalidFullCodegenState, "invalid full-codegen state") \
1139 V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \
1140 V(kInvalidLeftHandSideInAssignment, "Invalid left-hand side in assignment") \
1141 V(kInvalidLhsInCompoundAssignment, "Invalid lhs in compound assignment") \
1142 V(kInvalidLhsInCountOperation, "Invalid lhs in count operation") \
1143 V(kInvalidMinLength, "Invalid min_length") \
1144 V(kJSGlobalObjectNativeContextShouldBeANativeContext, \
1145 "JSGlobalObject::native_context should be a native context") \
1146 V(kJSGlobalProxyContextShouldNotBeNull, \
1147 "JSGlobalProxy::context() should not be null") \
1148 V(kJSObjectWithFastElementsMapHasSlowElements, \
1149 "JSObject with fast elements map has slow elements") \
1150 V(kLetBindingReInitialization, "Let binding re-initialization") \
1151 V(kLhsHasBeenClobbered, "lhs has been clobbered") \
1152 V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \
1153 V(kLiveEditFrameDroppingIsNotSupportedOnARM64, \
1154 "LiveEdit frame dropping is not supported on arm64") \
1155 V(kLiveEditFrameDroppingIsNotSupportedOnArm, \
1156 "LiveEdit frame dropping is not supported on arm") \
1157 V(kLiveEditFrameDroppingIsNotSupportedOnMips, \
1158 "LiveEdit frame dropping is not supported on mips") \
1159 V(kLiveEdit, "LiveEdit") \
1160 V(kLookupVariableInCountOperation, \
1161 "Lookup variable in count operation") \
1162 V(kMapBecameDeprecated, "Map became deprecated") \
1163 V(kMapBecameUnstable, "Map became unstable") \
1164 V(kMapIsNoLongerInEax, "Map is no longer in eax") \
1165 V(kModuleDeclaration, "Module declaration") \
1166 V(kModuleLiteral, "Module literal") \
1167 V(kModulePath, "Module path") \
1168 V(kModuleStatement, "Module statement") \
1169 V(kModuleVariable, "Module variable") \
1170 V(kModuleUrl, "Module url") \
1171 V(kNativeFunctionLiteral, "Native function literal") \
1172 V(kNeedSmiLiteral, "Need a Smi literal here") \
1173 V(kNoCasesLeft, "No cases left") \
1174 V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \
1175 "No empty arrays here in EmitFastAsciiArrayJoin") \
1176 V(kNonInitializerAssignmentToConst, \
1177 "Non-initializer assignment to const") \
1178 V(kNonSmiIndex, "Non-smi index") \
1179 V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal") \
1180 V(kNonSmiValue, "Non-smi value") \
1181 V(kNonObject, "Non-object value") \
1182 V(kNotEnoughVirtualRegistersForValues, \
1183 "Not enough virtual registers for values") \
1184 V(kNotEnoughSpillSlotsForOsr, \
1185 "Not enough spill slots for OSR") \
1186 V(kNotEnoughVirtualRegistersRegalloc, \
1187 "Not enough virtual registers (regalloc)") \
1188 V(kObjectFoundInSmiOnlyArray, "Object found in smi-only array") \
1189 V(kObjectLiteralWithComplexProperty, \
1190 "Object literal with complex property") \
1191 V(kOddballInStringTableIsNotUndefinedOrTheHole, \
1192 "Oddball in string table is not undefined or the hole") \
1193 V(kOffsetOutOfRange, "Offset out of range") \
1194 V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name") \
1195 V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string") \
1196 V(kOperandIsASmi, "Operand is a smi") \
1197 V(kOperandIsNotAName, "Operand is not a name") \
1198 V(kOperandIsNotANumber, "Operand is not a number") \
1199 V(kOperandIsNotASmi, "Operand is not a smi") \
1200 V(kOperandIsNotAString, "Operand is not a string") \
1201 V(kOperandIsNotSmi, "Operand is not smi") \
1202 V(kOperandNotANumber, "Operand not a number") \
1203 V(kObjectTagged, "The object is tagged") \
1204 V(kObjectNotTagged, "The object is not tagged") \
1205 V(kOptimizationDisabled, "Optimization is disabled") \
1206 V(kOptimizedTooManyTimes, "Optimized too many times") \
1207 V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister, \
1208 "Out of virtual registers while trying to allocate temp register") \
1209 V(kParseScopeError, "Parse/scope error") \
1210 V(kPossibleDirectCallToEval, "Possible direct call to eval") \
1211 V(kPreconditionsWereNotMet, "Preconditions were not met") \
1212 V(kPropertyAllocationCountFailed, "Property allocation count failed") \
1213 V(kReceivedInvalidReturnAddress, "Received invalid return address") \
1214 V(kReferenceToAVariableWhichRequiresDynamicLookup, \
1215 "Reference to a variable which requires dynamic lookup") \
1216 V(kReferenceToGlobalLexicalVariable, \
1217 "Reference to global lexical variable") \
1218 V(kReferenceToUninitializedVariable, "Reference to uninitialized variable") \
1219 V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \
1220 V(kRegisterWasClobbered, "Register was clobbered") \
1221 V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \
1222 V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \
1223 V(kRhsHasBeenClobbered, "Rhs has been clobbered") \
1224 V(kScopedBlock, "ScopedBlock") \
1225 V(kSmiAdditionOverflow, "Smi addition overflow") \
1226 V(kSmiSubtractionOverflow, "Smi subtraction overflow") \
1227 V(kStackAccessBelowStackPointer, "Stack access below stack pointer") \
1228 V(kStackFrameTypesMustMatch, "Stack frame types must match") \
1229 V(kSwitchStatementMixedOrNonLiteralSwitchLabels, \
1230 "SwitchStatement: mixed or non-literal switch labels") \
1231 V(kSwitchStatementTooManyClauses, "SwitchStatement: too many clauses") \
1232 V(kTheCurrentStackPointerIsBelowCsp, \
1233 "The current stack pointer is below csp") \
1234 V(kTheInstructionShouldBeALui, "The instruction should be a lui") \
1235 V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \
1236 V(kTheInstructionToPatchShouldBeALoadFromPc, \
1237 "The instruction to patch should be a load from pc") \
1238 V(kTheInstructionToPatchShouldBeALoadFromPp, \
1239 "The instruction to patch should be a load from pp") \
1240 V(kTheInstructionToPatchShouldBeAnLdrLiteral, \
1241 "The instruction to patch should be a ldr literal") \
1242 V(kTheInstructionToPatchShouldBeALui, \
1243 "The instruction to patch should be a lui") \
1244 V(kTheInstructionToPatchShouldBeAnOri, \
1245 "The instruction to patch should be an ori") \
1246 V(kTheSourceAndDestinationAreTheSame, \
1247 "The source and destination are the same") \
1248 V(kTheStackPointerIsNotAligned, "The stack pointer is not aligned.") \
1249 V(kTheStackWasCorruptedByMacroAssemblerCall, \
1250 "The stack was corrupted by MacroAssembler::Call()") \
1251 V(kTooManyParametersLocals, "Too many parameters/locals") \
1252 V(kTooManyParameters, "Too many parameters") \
1253 V(kTooManySpillSlotsNeededForOSR, "Too many spill slots needed for OSR") \
1254 V(kToOperand32UnsupportedImmediate, "ToOperand32 unsupported immediate.") \
1255 V(kToOperandIsDoubleRegisterUnimplemented, \
1256 "ToOperand IsDoubleRegister unimplemented") \
1257 V(kToOperandUnsupportedDoubleImmediate, \
1258 "ToOperand Unsupported double immediate") \
1259 V(kTryCatchStatement, "TryCatchStatement") \
1260 V(kTryFinallyStatement, "TryFinallyStatement") \
1261 V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi") \
1262 V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space") \
1263 V(kUnalignedCellInWriteBarrier, "Unaligned cell in write barrier") \
1264 V(kUndefinedValueNotLoaded, "Undefined value not loaded") \
1265 V(kUndoAllocationOfNonAllocatedMemory, \
1266 "Undo allocation of non allocated memory") \
1267 V(kUnexpectedAllocationTop, "Unexpected allocation top") \
1268 V(kUnexpectedColorFound, "Unexpected color bit pattern found") \
1269 V(kUnexpectedElementsKindInArrayConstructor, \
1270 "Unexpected ElementsKind in array constructor") \
1271 V(kUnexpectedFallthroughFromCharCodeAtSlowCase, \
1272 "Unexpected fallthrough from CharCodeAt slow case") \
1273 V(kUnexpectedFallthroughFromCharFromCodeSlowCase, \
1274 "Unexpected fallthrough from CharFromCode slow case") \
1275 V(kUnexpectedFallThroughFromStringComparison, \
1276 "Unexpected fall-through from string comparison") \
1277 V(kUnexpectedFallThroughInBinaryStubGenerateFloatingPointCode, \
1278 "Unexpected fall-through in BinaryStub_GenerateFloatingPointCode") \
1279 V(kUnexpectedFallthroughToCharCodeAtSlowCase, \
1280 "Unexpected fallthrough to CharCodeAt slow case") \
1281 V(kUnexpectedFallthroughToCharFromCodeSlowCase, \
1282 "Unexpected fallthrough to CharFromCode slow case") \
1283 V(kUnexpectedFPUStackDepthAfterInstruction, \
1284 "Unexpected FPU stack depth after instruction") \
1285 V(kUnexpectedInitialMapForArrayFunction1, \
1286 "Unexpected initial map for Array function (1)") \
1287 V(kUnexpectedInitialMapForArrayFunction2, \
1288 "Unexpected initial map for Array function (2)") \
1289 V(kUnexpectedInitialMapForArrayFunction, \
1290 "Unexpected initial map for Array function") \
1291 V(kUnexpectedInitialMapForInternalArrayFunction, \
1292 "Unexpected initial map for InternalArray function") \
1293 V(kUnexpectedLevelAfterReturnFromApiCall, \
1294 "Unexpected level after return from api call") \
1295 V(kUnexpectedNegativeValue, "Unexpected negative value") \
1296 V(kUnexpectedNumberOfPreAllocatedPropertyFields, \
1297 "Unexpected number of pre-allocated property fields") \
1298 V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \
1299 V(kUnexpectedSmi, "Unexpected smi value") \
1300 V(kUnexpectedStringFunction, "Unexpected String function") \
1301 V(kUnexpectedStringType, "Unexpected string type") \
1302 V(kUnexpectedStringWrapperInstanceSize, \
1303 "Unexpected string wrapper instance size") \
1304 V(kUnexpectedTypeForRegExpDataFixedArrayExpected, \
1305 "Unexpected type for RegExp data, FixedArray expected") \
1306 V(kUnexpectedValue, "Unexpected value") \
1307 V(kUnexpectedUnusedPropertiesOfStringWrapper, \
1308 "Unexpected unused properties of string wrapper") \
1309 V(kUnimplemented, "unimplemented") \
1310 V(kUninitializedKSmiConstantRegister, "Uninitialized kSmiConstantRegister") \
1311 V(kUnknown, "Unknown") \
1312 V(kUnsupportedConstCompoundAssignment, \
1313 "Unsupported const compound assignment") \
1314 V(kUnsupportedCountOperationWithConst, \
1315 "Unsupported count operation with const") \
1316 V(kUnsupportedDoubleImmediate, "Unsupported double immediate") \
1317 V(kUnsupportedLetCompoundAssignment, "Unsupported let compound assignment") \
1318 V(kUnsupportedLookupSlotInDeclaration, \
1319 "Unsupported lookup slot in declaration") \
1320 V(kUnsupportedNonPrimitiveCompare, "Unsupported non-primitive compare") \
1321 V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \
1322 V(kUnsupportedPhiUseOfConstVariable, \
1323 "Unsupported phi use of const variable") \
1324 V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \
1325 V(kVariableResolvedToWithContext, "Variable resolved to with context") \
1326 V(kWeShouldNotHaveAnEmptyLexicalContext, \
1327 "We should not have an empty lexical context") \
1328 V(kWithStatement, "WithStatement") \
1329 V(kWrongAddressOrValuePassedToRecordWrite, \
1330 "Wrong address or value passed to RecordWrite") \
1331 V(kYield, "Yield")
1332
1333
1334 #define ERROR_MESSAGES_CONSTANTS(C, T) C,
1335 enum BailoutReason {
1336 ERROR_MESSAGES_LIST(ERROR_MESSAGES_CONSTANTS)
1337 kLastErrorMessage
1338 };
1339 #undef ERROR_MESSAGES_CONSTANTS
1340
1341
1342 const char* GetBailoutReason(BailoutReason reason);
1343
1344
1345 // Object is the abstract superclass for all classes in the
1346 // object hierarchy.
1347 // Object does not use any virtual functions to avoid the
1348 // allocation of the C++ vtable.
1349 // Since both Smi and HeapObject are subclasses of Object no
1350 // data members can be present in Object.
1351 class Object {
1352 public:
1353 // Type testing.
IsObject()1354 bool IsObject() { return true; }
1355
1356 #define IS_TYPE_FUNCTION_DECL(type_) inline bool Is##type_();
1357 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1358 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1359 #undef IS_TYPE_FUNCTION_DECL
1360
1361 inline bool IsFixedArrayBase();
1362 inline bool IsExternal();
1363 inline bool IsAccessorInfo();
1364
1365 inline bool IsStruct();
1366 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
1367 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1368 #undef DECLARE_STRUCT_PREDICATE
1369
1370 INLINE(bool IsSpecObject());
1371 INLINE(bool IsSpecFunction());
1372 INLINE(bool IsTemplateInfo());
1373 bool IsCallable();
1374
1375 // Oddball testing.
1376 INLINE(bool IsUndefined());
1377 INLINE(bool IsNull());
1378 INLINE(bool IsTheHole());
1379 INLINE(bool IsException());
1380 INLINE(bool IsUninitialized());
1381 INLINE(bool IsTrue());
1382 INLINE(bool IsFalse());
1383 inline bool IsArgumentsMarker();
1384
1385 // Filler objects (fillers and free space objects).
1386 inline bool IsFiller();
1387
1388 // Extract the number.
1389 inline double Number();
1390 inline bool IsNaN();
1391 bool ToInt32(int32_t* value);
1392 bool ToUint32(uint32_t* value);
1393
1394 // Indicates whether OptimalRepresentation can do its work, or whether it
1395 // always has to return Representation::Tagged().
1396 enum ValueType {
1397 OPTIMAL_REPRESENTATION,
1398 FORCE_TAGGED
1399 };
1400
1401 inline Representation OptimalRepresentation(
1402 ValueType type = OPTIMAL_REPRESENTATION) {
1403 if (!FLAG_track_fields) return Representation::Tagged();
1404 if (type == FORCE_TAGGED) return Representation::Tagged();
1405 if (IsSmi()) {
1406 return Representation::Smi();
1407 } else if (FLAG_track_double_fields && IsHeapNumber()) {
1408 return Representation::Double();
1409 } else if (FLAG_track_computed_fields && IsUninitialized()) {
1410 return Representation::None();
1411 } else if (FLAG_track_heap_object_fields) {
1412 ASSERT(IsHeapObject());
1413 return Representation::HeapObject();
1414 } else {
1415 return Representation::Tagged();
1416 }
1417 }
1418
FitsRepresentation(Representation representation)1419 inline bool FitsRepresentation(Representation representation) {
1420 if (FLAG_track_fields && representation.IsNone()) {
1421 return false;
1422 } else if (FLAG_track_fields && representation.IsSmi()) {
1423 return IsSmi();
1424 } else if (FLAG_track_double_fields && representation.IsDouble()) {
1425 return IsNumber();
1426 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
1427 return IsHeapObject();
1428 }
1429 return true;
1430 }
1431
1432 Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
1433
1434 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1435 Handle<Object> object,
1436 Representation representation);
1437
1438 // Returns true if the object is of the correct type to be used as a
1439 // implementation of a JSObject's elements.
1440 inline bool HasValidElements();
1441
1442 inline bool HasSpecificClassOf(String* name);
1443
1444 bool BooleanValue(); // ECMA-262 9.2.
1445
1446 // Convert to a JSObject if needed.
1447 // native_context is used when creating wrapper object.
1448 static inline MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
1449 Handle<Object> object);
1450 static MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
1451 Handle<Object> object,
1452 Handle<Context> context);
1453
1454 // Converts this to a Smi if possible.
1455 static MUST_USE_RESULT inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
1456 Handle<Object> object);
1457
1458 void Lookup(Handle<Name> name, LookupResult* result);
1459
1460 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
1461 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1462 Handle<Object> object,
1463 Handle<Name> key);
1464 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1465 Isolate* isolate,
1466 Handle<Object> object,
1467 const char* key);
1468 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1469 Handle<Object> object,
1470 Handle<Name> key);
1471
1472 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
1473 Handle<Object> receiver,
1474 Handle<Name> name,
1475 Handle<JSObject> holder,
1476 Handle<Object> structure);
1477 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
1478 Handle<Object> receiver,
1479 Handle<Name> name,
1480 Handle<Object> value,
1481 Handle<JSObject> holder,
1482 Handle<Object> structure,
1483 StrictMode strict_mode);
1484
1485 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1486 Handle<Object> receiver,
1487 Handle<JSReceiver> getter);
1488 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
1489 Handle<Object> receiver,
1490 Handle<JSReceiver> setter,
1491 Handle<Object> value);
1492
1493 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
1494 Isolate* isolate,
1495 Handle<Object> object,
1496 uint32_t index);
1497
1498 MUST_USE_RESULT static MaybeHandle<Object> GetElementWithReceiver(
1499 Isolate* isolate,
1500 Handle<Object> object,
1501 Handle<Object> receiver,
1502 uint32_t index);
1503
1504 // Return the object's prototype (might be Heap::null_value()).
1505 Object* GetPrototype(Isolate* isolate);
1506 static Handle<Object> GetPrototype(Isolate* isolate, Handle<Object> object);
1507
1508 // Returns the permanent hash code associated with this object. May return
1509 // undefined if not yet created.
1510 Object* GetHash();
1511
1512 // Returns the permanent hash code associated with this object depending on
1513 // the actual object type. May create and store a hash code if needed and none
1514 // exists.
1515 static Handle<Smi> GetOrCreateHash(Isolate* isolate, Handle<Object> object);
1516
1517 // Checks whether this object has the same value as the given one. This
1518 // function is implemented according to ES5, section 9.12 and can be used
1519 // to implement the Harmony "egal" function.
1520 bool SameValue(Object* other);
1521
1522 // Checks whether this object has the same value as the given one.
1523 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1524 // This function is implemented according to ES6, section 7.2.4 and is used
1525 // by ES6 Map and Set.
1526 bool SameValueZero(Object* other);
1527
1528 // Tries to convert an object to an array index. Returns true and sets
1529 // the output parameter if it succeeds.
1530 inline bool ToArrayIndex(uint32_t* index);
1531
1532 // Returns true if this is a JSValue containing a string and the index is
1533 // < the length of the string. Used to implement [] on strings.
1534 inline bool IsStringObjectWithCharacterAt(uint32_t index);
1535
1536 DECLARE_VERIFIER(Object)
1537 #ifdef VERIFY_HEAP
1538 // Verify a pointer is a valid object pointer.
1539 static void VerifyPointer(Object* p);
1540 #endif
1541
1542 inline void VerifyApiCallResultType();
1543
1544 // Prints this object without details.
1545 void ShortPrint(FILE* out = stdout);
1546
1547 // Prints this object without details to a message accumulator.
1548 void ShortPrint(StringStream* accumulator);
1549
1550 // Casting: This cast is only needed to satisfy macros in objects-inl.h.
cast(Object * value)1551 static Object* cast(Object* value) { return value; }
1552
1553 // Layout description.
1554 static const int kHeaderSize = 0; // Object does not take up any space.
1555
1556 #ifdef OBJECT_PRINT
1557 // Prints this object with details.
1558 void Print();
1559 void Print(FILE* out);
1560 void PrintLn();
1561 void PrintLn(FILE* out);
1562 #endif
1563
1564 private:
1565 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1566 };
1567
1568
1569 // Smi represents integer Numbers that can be stored in 31 bits.
1570 // Smis are immediate which means they are NOT allocated in the heap.
1571 // The this pointer has the following format: [31 bit signed int] 0
1572 // For long smis it has the following format:
1573 // [32 bit signed int] [31 bits zero padding] 0
1574 // Smi stands for small integer.
1575 class Smi: public Object {
1576 public:
1577 // Returns the integer value.
1578 inline int value();
1579
1580 // Convert a value to a Smi object.
1581 static inline Smi* FromInt(int value);
1582
1583 static inline Smi* FromIntptr(intptr_t value);
1584
1585 // Returns whether value can be represented in a Smi.
1586 static inline bool IsValid(intptr_t value);
1587
1588 // Casting.
1589 static inline Smi* cast(Object* object);
1590
1591 // Dispatched behavior.
1592 void SmiPrint(FILE* out = stdout);
1593 void SmiPrint(StringStream* accumulator);
1594
1595 DECLARE_VERIFIER(Smi)
1596
1597 static const int kMinValue =
1598 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
1599 static const int kMaxValue = -(kMinValue + 1);
1600
1601 private:
1602 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1603 };
1604
1605
1606 // Heap objects typically have a map pointer in their first word. However,
1607 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1608 // encoded in the first word. The class MapWord is an abstraction of the
1609 // value in a heap object's first word.
1610 class MapWord BASE_EMBEDDED {
1611 public:
1612 // Normal state: the map word contains a map pointer.
1613
1614 // Create a map word from a map pointer.
1615 static inline MapWord FromMap(Map* map);
1616
1617 // View this map word as a map pointer.
1618 inline Map* ToMap();
1619
1620
1621 // Scavenge collection: the map word of live objects in the from space
1622 // contains a forwarding address (a heap object pointer in the to space).
1623
1624 // True if this map word is a forwarding address for a scavenge
1625 // collection. Only valid during a scavenge collection (specifically,
1626 // when all map words are heap object pointers, i.e. not during a full GC).
1627 inline bool IsForwardingAddress();
1628
1629 // Create a map word from a forwarding address.
1630 static inline MapWord FromForwardingAddress(HeapObject* object);
1631
1632 // View this map word as a forwarding address.
1633 inline HeapObject* ToForwardingAddress();
1634
FromRawValue(uintptr_t value)1635 static inline MapWord FromRawValue(uintptr_t value) {
1636 return MapWord(value);
1637 }
1638
ToRawValue()1639 inline uintptr_t ToRawValue() {
1640 return value_;
1641 }
1642
1643 private:
1644 // HeapObject calls the private constructor and directly reads the value.
1645 friend class HeapObject;
1646
MapWord(uintptr_t value)1647 explicit MapWord(uintptr_t value) : value_(value) {}
1648
1649 uintptr_t value_;
1650 };
1651
1652
1653 // HeapObject is the superclass for all classes describing heap allocated
1654 // objects.
1655 class HeapObject: public Object {
1656 public:
1657 // [map]: Contains a map which contains the object's reflective
1658 // information.
1659 inline Map* map();
1660 inline void set_map(Map* value);
1661 // The no-write-barrier version. This is OK if the object is white and in
1662 // new space, or if the value is an immortal immutable object, like the maps
1663 // of primitive (non-JS) objects like strings, heap numbers etc.
1664 inline void set_map_no_write_barrier(Map* value);
1665
1666 // Get the map using acquire load.
1667 inline Map* synchronized_map();
1668 inline MapWord synchronized_map_word();
1669
1670 // Set the map using release store
1671 inline void synchronized_set_map(Map* value);
1672 inline void synchronized_set_map_no_write_barrier(Map* value);
1673 inline void synchronized_set_map_word(MapWord map_word);
1674
1675 // During garbage collection, the map word of a heap object does not
1676 // necessarily contain a map pointer.
1677 inline MapWord map_word();
1678 inline void set_map_word(MapWord map_word);
1679
1680 // The Heap the object was allocated in. Used also to access Isolate.
1681 inline Heap* GetHeap();
1682
1683 // Convenience method to get current isolate.
1684 inline Isolate* GetIsolate();
1685
1686 // Converts an address to a HeapObject pointer.
1687 static inline HeapObject* FromAddress(Address address);
1688
1689 // Returns the address of this HeapObject.
1690 inline Address address();
1691
1692 // Iterates over pointers contained in the object (including the Map)
1693 void Iterate(ObjectVisitor* v);
1694
1695 // Iterates over all pointers contained in the object except the
1696 // first map pointer. The object type is given in the first
1697 // parameter. This function does not access the map pointer in the
1698 // object, and so is safe to call while the map pointer is modified.
1699 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1700
1701 // Returns the heap object's size in bytes
1702 inline int Size();
1703
1704 // Given a heap object's map pointer, returns the heap size in bytes
1705 // Useful when the map pointer field is used for other purposes.
1706 // GC internal.
1707 inline int SizeFromMap(Map* map);
1708
1709 // Returns the field at offset in obj, as a read/write Object* reference.
1710 // Does no checking, and is safe to use during GC, while maps are invalid.
1711 // Does not invoke write barrier, so should only be assigned to
1712 // during marking GC.
1713 static inline Object** RawField(HeapObject* obj, int offset);
1714
1715 // Adds the |code| object related to |name| to the code cache of this map. If
1716 // this map is a dictionary map that is shared, the map copied and installed
1717 // onto the object.
1718 static void UpdateMapCodeCache(Handle<HeapObject> object,
1719 Handle<Name> name,
1720 Handle<Code> code);
1721
1722 // Casting.
1723 static inline HeapObject* cast(Object* obj);
1724
1725 // Return the write barrier mode for this. Callers of this function
1726 // must be able to present a reference to an DisallowHeapAllocation
1727 // object as a sign that they are not going to use this function
1728 // from code that allocates and thus invalidates the returned write
1729 // barrier mode.
1730 inline WriteBarrierMode GetWriteBarrierMode(
1731 const DisallowHeapAllocation& promise);
1732
1733 // Dispatched behavior.
1734 void HeapObjectShortPrint(StringStream* accumulator);
1735 #ifdef OBJECT_PRINT
1736 void PrintHeader(FILE* out, const char* id);
1737 #endif
1738 DECLARE_PRINTER(HeapObject)
1739 DECLARE_VERIFIER(HeapObject)
1740 #ifdef VERIFY_HEAP
1741 inline void VerifyObjectField(int offset);
1742 inline void VerifySmiField(int offset);
1743
1744 // Verify a pointer is a valid HeapObject pointer that points to object
1745 // areas in the heap.
1746 static void VerifyHeapPointer(Object* p);
1747 #endif
1748
1749 // Layout description.
1750 // First field in a heap object is map.
1751 static const int kMapOffset = Object::kHeaderSize;
1752 static const int kHeaderSize = kMapOffset + kPointerSize;
1753
1754 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
1755
1756 protected:
1757 // helpers for calling an ObjectVisitor to iterate over pointers in the
1758 // half-open range [start, end) specified as integer offsets
1759 inline void IteratePointers(ObjectVisitor* v, int start, int end);
1760 // as above, for the single element at "offset"
1761 inline void IteratePointer(ObjectVisitor* v, int offset);
1762 // as above, for the next code link of a code object.
1763 inline void IterateNextCodeLink(ObjectVisitor* v, int offset);
1764
1765 private:
1766 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1767 };
1768
1769
1770 // This class describes a body of an object of a fixed size
1771 // in which all pointer fields are located in the [start_offset, end_offset)
1772 // interval.
1773 template<int start_offset, int end_offset, int size>
1774 class FixedBodyDescriptor {
1775 public:
1776 static const int kStartOffset = start_offset;
1777 static const int kEndOffset = end_offset;
1778 static const int kSize = size;
1779
1780 static inline void IterateBody(HeapObject* obj, ObjectVisitor* v);
1781
1782 template<typename StaticVisitor>
IterateBody(HeapObject * obj)1783 static inline void IterateBody(HeapObject* obj) {
1784 StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
1785 HeapObject::RawField(obj, end_offset));
1786 }
1787 };
1788
1789
1790 // This class describes a body of an object of a variable size
1791 // in which all pointer fields are located in the [start_offset, object_size)
1792 // interval.
1793 template<int start_offset>
1794 class FlexibleBodyDescriptor {
1795 public:
1796 static const int kStartOffset = start_offset;
1797
1798 static inline void IterateBody(HeapObject* obj,
1799 int object_size,
1800 ObjectVisitor* v);
1801
1802 template<typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)1803 static inline void IterateBody(HeapObject* obj, int object_size) {
1804 StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
1805 HeapObject::RawField(obj, object_size));
1806 }
1807 };
1808
1809
1810 // The HeapNumber class describes heap allocated numbers that cannot be
1811 // represented in a Smi (small integer)
1812 class HeapNumber: public HeapObject {
1813 public:
1814 // [value]: number value.
1815 inline double value();
1816 inline void set_value(double value);
1817
1818 // Casting.
1819 static inline HeapNumber* cast(Object* obj);
1820
1821 // Dispatched behavior.
1822 bool HeapNumberBooleanValue();
1823
1824 void HeapNumberPrint(FILE* out = stdout);
1825 void HeapNumberPrint(StringStream* accumulator);
1826 DECLARE_VERIFIER(HeapNumber)
1827
1828 inline int get_exponent();
1829 inline int get_sign();
1830
1831 // Layout description.
1832 static const int kValueOffset = HeapObject::kHeaderSize;
1833 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
1834 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1835 // words within double numbers are endian dependent and they are set
1836 // accordingly.
1837 #if defined(V8_TARGET_LITTLE_ENDIAN)
1838 static const int kMantissaOffset = kValueOffset;
1839 static const int kExponentOffset = kValueOffset + 4;
1840 #elif defined(V8_TARGET_BIG_ENDIAN)
1841 static const int kMantissaOffset = kValueOffset + 4;
1842 static const int kExponentOffset = kValueOffset;
1843 #else
1844 #error Unknown byte ordering
1845 #endif
1846
1847 static const int kSize = kValueOffset + kDoubleSize;
1848 static const uint32_t kSignMask = 0x80000000u;
1849 static const uint32_t kExponentMask = 0x7ff00000u;
1850 static const uint32_t kMantissaMask = 0xfffffu;
1851 static const int kMantissaBits = 52;
1852 static const int kExponentBits = 11;
1853 static const int kExponentBias = 1023;
1854 static const int kExponentShift = 20;
1855 static const int kInfinityOrNanExponent =
1856 (kExponentMask >> kExponentShift) - kExponentBias;
1857 static const int kMantissaBitsInTopWord = 20;
1858 static const int kNonMantissaBitsInTopWord = 12;
1859
1860 private:
1861 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1862 };
1863
1864
1865 enum EnsureElementsMode {
1866 DONT_ALLOW_DOUBLE_ELEMENTS,
1867 ALLOW_COPIED_DOUBLE_ELEMENTS,
1868 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1869 };
1870
1871
1872 // Indicates whether a property should be set or (re)defined. Setting of a
1873 // property causes attributes to remain unchanged, writability to be checked
1874 // and callbacks to be called. Defining of a property causes attributes to
1875 // be updated and callbacks to be overridden.
1876 enum SetPropertyMode {
1877 SET_PROPERTY,
1878 DEFINE_PROPERTY
1879 };
1880
1881
1882 // Indicator for one component of an AccessorPair.
1883 enum AccessorComponent {
1884 ACCESSOR_GETTER,
1885 ACCESSOR_SETTER
1886 };
1887
1888
1889 // JSReceiver includes types on which properties can be defined, i.e.,
1890 // JSObject and JSProxy.
1891 class JSReceiver: public HeapObject {
1892 public:
1893 enum DeleteMode {
1894 NORMAL_DELETION,
1895 STRICT_DELETION,
1896 FORCE_DELETION
1897 };
1898
1899 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1900 // a keyed store is of the form a[expression] = foo.
1901 enum StoreFromKeyed {
1902 MAY_BE_STORE_FROM_KEYED,
1903 CERTAINLY_NOT_STORE_FROM_KEYED
1904 };
1905
1906 // Internal properties (e.g. the hidden properties dictionary) might
1907 // be added even though the receiver is non-extensible.
1908 enum ExtensibilityCheck {
1909 PERFORM_EXTENSIBILITY_CHECK,
1910 OMIT_EXTENSIBILITY_CHECK
1911 };
1912
1913 // Casting.
1914 static inline JSReceiver* cast(Object* obj);
1915
1916 // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
1917 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
1918 Handle<JSReceiver> object,
1919 Handle<Name> key,
1920 Handle<Object> value,
1921 PropertyAttributes attributes,
1922 StrictMode strict_mode,
1923 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
1924 MUST_USE_RESULT static MaybeHandle<Object> SetElement(
1925 Handle<JSReceiver> object,
1926 uint32_t index,
1927 Handle<Object> value,
1928 PropertyAttributes attributes,
1929 StrictMode strict_mode);
1930
1931 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
1932 static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
1933 static inline bool HasOwnProperty(Handle<JSReceiver>, Handle<Name> name);
1934 static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
1935 static inline bool HasOwnElement(Handle<JSReceiver> object, uint32_t index);
1936
1937 // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
1938 MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
1939 Handle<JSReceiver> object,
1940 Handle<Name> name,
1941 DeleteMode mode = NORMAL_DELETION);
1942 MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
1943 Handle<JSReceiver> object,
1944 uint32_t index,
1945 DeleteMode mode = NORMAL_DELETION);
1946
1947 // Tests for the fast common case for property enumeration.
1948 bool IsSimpleEnum();
1949
1950 // Returns the class name ([[Class]] property in the specification).
1951 String* class_name();
1952
1953 // Returns the constructor name (the name (possibly, inferred name) of the
1954 // function that was used to instantiate the object).
1955 String* constructor_name();
1956
1957 static inline PropertyAttributes GetPropertyAttributes(
1958 Handle<JSReceiver> object,
1959 Handle<Name> name);
1960 static PropertyAttributes GetPropertyAttributes(LookupIterator* it);
1961 static PropertyAttributes GetOwnPropertyAttributes(
1962 Handle<JSReceiver> object,
1963 Handle<Name> name);
1964
1965 static inline PropertyAttributes GetElementAttribute(
1966 Handle<JSReceiver> object,
1967 uint32_t index);
1968 static inline PropertyAttributes GetOwnElementAttribute(
1969 Handle<JSReceiver> object,
1970 uint32_t index);
1971
1972 // Return the object's prototype (might be Heap::null_value()).
1973 inline Object* GetPrototype();
1974
1975 // Return the constructor function (may be Heap::null_value()).
1976 inline Object* GetConstructor();
1977
1978 // Retrieves a permanent object identity hash code. The undefined value might
1979 // be returned in case no hash was created yet.
1980 inline Object* GetIdentityHash();
1981
1982 // Retrieves a permanent object identity hash code. May create and store a
1983 // hash code if needed and none exists.
1984 inline static Handle<Smi> GetOrCreateIdentityHash(
1985 Handle<JSReceiver> object);
1986
1987 // Lookup a property. If found, the result is valid and has
1988 // detailed information.
1989 void LookupOwn(Handle<Name> name, LookupResult* result,
1990 bool search_hidden_prototypes = false);
1991 void Lookup(Handle<Name> name, LookupResult* result);
1992
1993 enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
1994
1995 // Computes the enumerable keys for a JSObject. Used for implementing
1996 // "for (n in object) { }".
1997 MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
1998 Handle<JSReceiver> object,
1999 KeyCollectionType type);
2000
2001 private:
2002 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
2003 Handle<JSReceiver> receiver,
2004 LookupResult* result,
2005 Handle<Name> key,
2006 Handle<Object> value,
2007 PropertyAttributes attributes,
2008 StrictMode strict_mode,
2009 StoreFromKeyed store_from_keyed);
2010
2011 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
2012 };
2013
2014 // Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
2015 class ObjectHashTable;
2016
2017 // Forward declaration for JSObject::Copy.
2018 class AllocationSite;
2019
2020
2021 // The JSObject describes real heap allocated JavaScript objects with
2022 // properties.
2023 // Note that the map of JSObject changes during execution to enable inline
2024 // caching.
2025 class JSObject: public JSReceiver {
2026 public:
2027 // [properties]: Backing storage for properties.
2028 // properties is a FixedArray in the fast case and a Dictionary in the
2029 // slow case.
2030 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
2031 inline void initialize_properties();
2032 inline bool HasFastProperties();
2033 inline NameDictionary* property_dictionary(); // Gets slow properties.
2034
2035 // [elements]: The elements (properties with names that are integers).
2036 //
2037 // Elements can be in two general modes: fast and slow. Each mode
2038 // corrensponds to a set of object representations of elements that
2039 // have something in common.
2040 //
2041 // In the fast mode elements is a FixedArray and so each element can
2042 // be quickly accessed. This fact is used in the generated code. The
2043 // elements array can have one of three maps in this mode:
2044 // fixed_array_map, sloppy_arguments_elements_map or
2045 // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2046 // the elements array may be shared by a few objects and so before
2047 // writing to any element the array must be copied. Use
2048 // EnsureWritableFastElements in this case.
2049 //
2050 // In the slow mode the elements is either a NumberDictionary, an
2051 // ExternalArray, or a FixedArray parameter map for a (sloppy)
2052 // arguments object.
2053 DECL_ACCESSORS(elements, FixedArrayBase)
2054 inline void initialize_elements();
2055 static void ResetElements(Handle<JSObject> object);
2056 static inline void SetMapAndElements(Handle<JSObject> object,
2057 Handle<Map> map,
2058 Handle<FixedArrayBase> elements);
2059 inline ElementsKind GetElementsKind();
2060 inline ElementsAccessor* GetElementsAccessor();
2061 // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
2062 inline bool HasFastSmiElements();
2063 // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
2064 inline bool HasFastObjectElements();
2065 // Returns true if an object has elements of FAST_ELEMENTS or
2066 // FAST_SMI_ONLY_ELEMENTS.
2067 inline bool HasFastSmiOrObjectElements();
2068 // Returns true if an object has any of the fast elements kinds.
2069 inline bool HasFastElements();
2070 // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
2071 // ElementsKind.
2072 inline bool HasFastDoubleElements();
2073 // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
2074 // ElementsKind.
2075 inline bool HasFastHoleyElements();
2076 inline bool HasSloppyArgumentsElements();
2077 inline bool HasDictionaryElements();
2078
2079 inline bool HasExternalUint8ClampedElements();
2080 inline bool HasExternalArrayElements();
2081 inline bool HasExternalInt8Elements();
2082 inline bool HasExternalUint8Elements();
2083 inline bool HasExternalInt16Elements();
2084 inline bool HasExternalUint16Elements();
2085 inline bool HasExternalInt32Elements();
2086 inline bool HasExternalUint32Elements();
2087 inline bool HasExternalFloat32Elements();
2088 inline bool HasExternalFloat64Elements();
2089
2090 inline bool HasFixedTypedArrayElements();
2091
2092 inline bool HasFixedUint8ClampedElements();
2093 inline bool HasFixedArrayElements();
2094 inline bool HasFixedInt8Elements();
2095 inline bool HasFixedUint8Elements();
2096 inline bool HasFixedInt16Elements();
2097 inline bool HasFixedUint16Elements();
2098 inline bool HasFixedInt32Elements();
2099 inline bool HasFixedUint32Elements();
2100 inline bool HasFixedFloat32Elements();
2101 inline bool HasFixedFloat64Elements();
2102
2103 bool HasFastArgumentsElements();
2104 bool HasDictionaryArgumentsElements();
2105 inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
2106
2107 // Requires: HasFastElements().
2108 static Handle<FixedArray> EnsureWritableFastElements(
2109 Handle<JSObject> object);
2110
2111 // Collects elements starting at index 0.
2112 // Undefined values are placed after non-undefined values.
2113 // Returns the number of non-undefined values.
2114 static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
2115 uint32_t limit);
2116 // As PrepareElementsForSort, but only on objects where elements is
2117 // a dictionary, and it will stay a dictionary. Collates undefined and
2118 // unexisting elements below limit from position zero of the elements.
2119 static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
2120 uint32_t limit);
2121
2122 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
2123 Handle<JSObject> object,
2124 Handle<Name> name,
2125 Handle<Object> value,
2126 PropertyAttributes attributes,
2127 StrictMode strict_mode);
2128
2129 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyForResult(
2130 Handle<JSObject> object,
2131 LookupResult* result,
2132 Handle<Name> name,
2133 Handle<Object> value,
2134 PropertyAttributes attributes,
2135 StrictMode strict_mode,
2136 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
2137
2138 // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
2139 // grant an exemption to ExecutableAccessor callbacks in some cases.
2140 enum ExecutableAccessorInfoHandling {
2141 DEFAULT_HANDLING,
2142 DONT_FORCE_FIELD
2143 };
2144
2145 MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
2146 Handle<JSObject> object,
2147 Handle<Name> key,
2148 Handle<Object> value,
2149 PropertyAttributes attributes,
2150 ValueType value_type = OPTIMAL_REPRESENTATION,
2151 StoreMode mode = ALLOW_AS_CONSTANT,
2152 ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
2153 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
2154 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
2155
2156 static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
2157 static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
2158
2159 // Try to follow an existing transition to a field with attributes NONE. The
2160 // return value indicates whether the transition was successful.
2161 static inline Handle<Map> FindTransitionToField(Handle<Map> map,
2162 Handle<Name> key);
2163
2164 // Extend the receiver with a single fast property appeared first in the
2165 // passed map. This also extends the property backing store if necessary.
2166 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
2167
2168 // Migrates the given object to a map whose field representations are the
2169 // lowest upper bound of all known representations for that field.
2170 static void MigrateInstance(Handle<JSObject> instance);
2171
2172 // Migrates the given object only if the target map is already available,
2173 // or returns false if such a map is not yet available.
2174 static bool TryMigrateInstance(Handle<JSObject> instance);
2175
2176 // Retrieve a value in a normalized object given a lookup result.
2177 // Handles the special representation of JS global objects.
2178 Object* GetNormalizedProperty(const LookupResult* result);
2179 static Handle<Object> GetNormalizedProperty(Handle<JSObject> object,
2180 const LookupResult* result);
2181
2182 // Sets the property value in a normalized object given a lookup result.
2183 // Handles the special representation of JS global objects.
2184 static void SetNormalizedProperty(Handle<JSObject> object,
2185 const LookupResult* result,
2186 Handle<Object> value);
2187
2188 // Sets the property value in a normalized object given (key, value, details).
2189 // Handles the special representation of JS global objects.
2190 static void SetNormalizedProperty(Handle<JSObject> object,
2191 Handle<Name> key,
2192 Handle<Object> value,
2193 PropertyDetails details);
2194
2195 static void OptimizeAsPrototype(Handle<JSObject> object);
2196
2197 // Retrieve interceptors.
2198 InterceptorInfo* GetNamedInterceptor();
2199 InterceptorInfo* GetIndexedInterceptor();
2200
2201 // Used from JSReceiver.
2202 static Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptor(
2203 Handle<JSObject> holder,
2204 Handle<Object> receiver,
2205 Handle<Name> name);
2206 static PropertyAttributes GetPropertyAttributesWithFailedAccessCheck(
2207 LookupIterator* it);
2208 static PropertyAttributes GetElementAttributeWithReceiver(
2209 Handle<JSObject> object,
2210 Handle<JSReceiver> receiver,
2211 uint32_t index,
2212 bool check_prototype);
2213
2214 // Retrieves an AccessorPair property from the given object. Might return
2215 // undefined if the property doesn't exist or is of a different kind.
2216 MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
2217 Handle<JSObject> object,
2218 Handle<Name> name,
2219 AccessorComponent component);
2220
2221 // Defines an AccessorPair property on the given object.
2222 // TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
2223 // exception instead of letting callers check for scheduled exception.
2224 static void DefineAccessor(Handle<JSObject> object,
2225 Handle<Name> name,
2226 Handle<Object> getter,
2227 Handle<Object> setter,
2228 PropertyAttributes attributes,
2229 v8::AccessControl access_control = v8::DEFAULT);
2230
2231 // Defines an AccessorInfo property on the given object.
2232 MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
2233 Handle<JSObject> object,
2234 Handle<AccessorInfo> info);
2235
2236 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
2237 Handle<JSObject> object,
2238 Handle<Object> receiver,
2239 Handle<Name> name);
2240
2241 // Returns true if this is an instance of an api function and has
2242 // been modified since it was created. May give false positives.
2243 bool IsDirty();
2244
2245 // Accessors for hidden properties object.
2246 //
2247 // Hidden properties are not own properties of the object itself.
2248 // Instead they are stored in an auxiliary structure kept as an own
2249 // property with a special name Heap::hidden_string(). But if the
2250 // receiver is a JSGlobalProxy then the auxiliary object is a property
2251 // of its prototype, and if it's a detached proxy, then you can't have
2252 // hidden properties.
2253
2254 // Sets a hidden property on this object. Returns this object if successful,
2255 // undefined if called on a detached proxy.
2256 static Handle<Object> SetHiddenProperty(Handle<JSObject> object,
2257 Handle<Name> key,
2258 Handle<Object> value);
2259 // Gets the value of a hidden property with the given key. Returns the hole
2260 // if the property doesn't exist (or if called on a detached proxy),
2261 // otherwise returns the value set for the key.
2262 Object* GetHiddenProperty(Handle<Name> key);
2263 // Deletes a hidden property. Deleting a non-existing property is
2264 // considered successful.
2265 static void DeleteHiddenProperty(Handle<JSObject> object,
2266 Handle<Name> key);
2267 // Returns true if the object has a property with the hidden string as name.
2268 static bool HasHiddenProperties(Handle<JSObject> object);
2269
2270 static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
2271
2272 static inline void ValidateElements(Handle<JSObject> object);
2273
2274 // Makes sure that this object can contain HeapObject as elements.
2275 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
2276
2277 // Makes sure that this object can contain the specified elements.
2278 static inline void EnsureCanContainElements(
2279 Handle<JSObject> object,
2280 Object** elements,
2281 uint32_t count,
2282 EnsureElementsMode mode);
2283 static inline void EnsureCanContainElements(
2284 Handle<JSObject> object,
2285 Handle<FixedArrayBase> elements,
2286 uint32_t length,
2287 EnsureElementsMode mode);
2288 static void EnsureCanContainElements(
2289 Handle<JSObject> object,
2290 Arguments* arguments,
2291 uint32_t first_arg,
2292 uint32_t arg_count,
2293 EnsureElementsMode mode);
2294
2295 // Would we convert a fast elements array to dictionary mode given
2296 // an access at key?
2297 bool WouldConvertToSlowElements(Handle<Object> key);
2298 // Do we want to keep the elements in fast case when increasing the
2299 // capacity?
2300 bool ShouldConvertToSlowElements(int new_capacity);
2301 // Returns true if the backing storage for the slow-case elements of
2302 // this object takes up nearly as much space as a fast-case backing
2303 // storage would. In that case the JSObject should have fast
2304 // elements.
2305 bool ShouldConvertToFastElements();
2306 // Returns true if the elements of JSObject contains only values that can be
2307 // represented in a FixedDoubleArray and has at least one value that can only
2308 // be represented as a double and not a Smi.
2309 bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
2310
2311 // Computes the new capacity when expanding the elements of a JSObject.
NewElementsCapacity(int old_capacity)2312 static int NewElementsCapacity(int old_capacity) {
2313 // (old_capacity + 50%) + 16
2314 return old_capacity + (old_capacity >> 1) + 16;
2315 }
2316
2317 // These methods do not perform access checks!
2318 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnPropertyAccessorPair(
2319 Handle<JSObject> object,
2320 Handle<Name> name);
2321 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnElementAccessorPair(
2322 Handle<JSObject> object,
2323 uint32_t index);
2324
2325 MUST_USE_RESULT static MaybeHandle<Object> SetFastElement(
2326 Handle<JSObject> object,
2327 uint32_t index,
2328 Handle<Object> value,
2329 StrictMode strict_mode,
2330 bool check_prototype);
2331
2332 MUST_USE_RESULT static MaybeHandle<Object> SetOwnElement(
2333 Handle<JSObject> object,
2334 uint32_t index,
2335 Handle<Object> value,
2336 StrictMode strict_mode);
2337
2338 // Empty handle is returned if the element cannot be set to the given value.
2339 MUST_USE_RESULT static MaybeHandle<Object> SetElement(
2340 Handle<JSObject> object,
2341 uint32_t index,
2342 Handle<Object> value,
2343 PropertyAttributes attributes,
2344 StrictMode strict_mode,
2345 bool check_prototype = true,
2346 SetPropertyMode set_mode = SET_PROPERTY);
2347
2348 // Returns the index'th element.
2349 // The undefined object if index is out of bounds.
2350 MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
2351 Handle<JSObject> object,
2352 Handle<Object> receiver,
2353 uint32_t index);
2354
2355 enum SetFastElementsCapacitySmiMode {
2356 kAllowSmiElements,
2357 kForceSmiElements,
2358 kDontAllowSmiElements
2359 };
2360
2361 // Replace the elements' backing store with fast elements of the given
2362 // capacity. Update the length for JSArrays. Returns the new backing
2363 // store.
2364 static Handle<FixedArray> SetFastElementsCapacityAndLength(
2365 Handle<JSObject> object,
2366 int capacity,
2367 int length,
2368 SetFastElementsCapacitySmiMode smi_mode);
2369 static void SetFastDoubleElementsCapacityAndLength(
2370 Handle<JSObject> object,
2371 int capacity,
2372 int length);
2373
2374 // Lookup interceptors are used for handling properties controlled by host
2375 // objects.
2376 inline bool HasNamedInterceptor();
2377 inline bool HasIndexedInterceptor();
2378
2379 // Computes the enumerable keys from interceptors. Used for debug mirrors and
2380 // by JSReceiver::GetKeys.
2381 MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForNamedInterceptor(
2382 Handle<JSObject> object,
2383 Handle<JSReceiver> receiver);
2384 MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForIndexedInterceptor(
2385 Handle<JSObject> object,
2386 Handle<JSReceiver> receiver);
2387
2388 // Support functions for v8 api (needed for correct interceptor behavior).
2389 static bool HasRealNamedProperty(Handle<JSObject> object,
2390 Handle<Name> key);
2391 static bool HasRealElementProperty(Handle<JSObject> object, uint32_t index);
2392 static bool HasRealNamedCallbackProperty(Handle<JSObject> object,
2393 Handle<Name> key);
2394
2395 // Get the header size for a JSObject. Used to compute the index of
2396 // internal fields as well as the number of internal fields.
2397 inline int GetHeaderSize();
2398
2399 inline int GetInternalFieldCount();
2400 inline int GetInternalFieldOffset(int index);
2401 inline Object* GetInternalField(int index);
2402 inline void SetInternalField(int index, Object* value);
2403 inline void SetInternalField(int index, Smi* value);
2404
2405 // The following lookup functions skip interceptors.
2406 void LookupOwnRealNamedProperty(Handle<Name> name, LookupResult* result);
2407 void LookupRealNamedProperty(Handle<Name> name, LookupResult* result);
2408 void LookupRealNamedPropertyInPrototypes(Handle<Name> name,
2409 LookupResult* result);
2410
2411 // Returns the number of properties on this object filtering out properties
2412 // with the specified attributes (ignoring interceptors).
2413 int NumberOfOwnProperties(PropertyAttributes filter = NONE);
2414 // Fill in details for properties into storage starting at the specified
2415 // index.
2416 void GetOwnPropertyNames(
2417 FixedArray* storage, int index, PropertyAttributes filter = NONE);
2418
2419 // Returns the number of properties on this object filtering out properties
2420 // with the specified attributes (ignoring interceptors).
2421 int NumberOfOwnElements(PropertyAttributes filter);
2422 // Returns the number of enumerable elements (ignoring interceptors).
2423 int NumberOfEnumElements();
2424 // Returns the number of elements on this object filtering out elements
2425 // with the specified attributes (ignoring interceptors).
2426 int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter);
2427 // Count and fill in the enumerable elements into storage.
2428 // (storage->length() == NumberOfEnumElements()).
2429 // If storage is NULL, will count the elements without adding
2430 // them to any storage.
2431 // Returns the number of enumerable elements.
2432 int GetEnumElementKeys(FixedArray* storage);
2433
2434 // Returns a new map with all transitions dropped from the object's current
2435 // map and the ElementsKind set.
2436 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2437 ElementsKind to_kind);
2438 static void TransitionElementsKind(Handle<JSObject> object,
2439 ElementsKind to_kind);
2440
2441 // TODO(mstarzinger): Both public because of ConvertAndSetOwnProperty().
2442 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
2443 static void GeneralizeFieldRepresentation(Handle<JSObject> object,
2444 int modify_index,
2445 Representation new_representation,
2446 Handle<HeapType> new_field_type,
2447 StoreMode store_mode);
2448
2449 // Convert the object to use the canonical dictionary
2450 // representation. If the object is expected to have additional properties
2451 // added this number can be indicated to have the backing store allocated to
2452 // an initial capacity for holding these properties.
2453 static void NormalizeProperties(Handle<JSObject> object,
2454 PropertyNormalizationMode mode,
2455 int expected_additional_properties);
2456
2457 // Convert and update the elements backing store to be a
2458 // SeededNumberDictionary dictionary. Returns the backing after conversion.
2459 static Handle<SeededNumberDictionary> NormalizeElements(
2460 Handle<JSObject> object);
2461
2462 // Transform slow named properties to fast variants.
2463 static void TransformToFastProperties(Handle<JSObject> object,
2464 int unused_property_fields);
2465
2466 // Access fast-case object properties at index.
2467 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2468 Representation representation,
2469 FieldIndex index);
2470 inline Object* RawFastPropertyAt(FieldIndex index);
2471 inline void FastPropertyAtPut(FieldIndex index, Object* value);
2472 void WriteToField(int descriptor, Object* value);
2473
2474 // Access to in object properties.
2475 inline int GetInObjectPropertyOffset(int index);
2476 inline Object* InObjectPropertyAt(int index);
2477 inline Object* InObjectPropertyAtPut(int index,
2478 Object* value,
2479 WriteBarrierMode mode
2480 = UPDATE_WRITE_BARRIER);
2481
2482 // Set the object's prototype (only JSReceiver and null are allowed values).
2483 MUST_USE_RESULT static MaybeHandle<Object> SetPrototype(
2484 Handle<JSObject> object,
2485 Handle<Object> value,
2486 bool skip_hidden_prototypes = false);
2487
2488 // Initializes the body after properties slot, properties slot is
2489 // initialized by set_properties. Fill the pre-allocated fields with
2490 // pre_allocated_value and the rest with filler_value.
2491 // Note: this call does not update write barrier, the caller is responsible
2492 // to ensure that |filler_value| can be collected without WB here.
2493 inline void InitializeBody(Map* map,
2494 Object* pre_allocated_value,
2495 Object* filler_value);
2496
2497 // Check whether this object references another object
2498 bool ReferencesObject(Object* obj);
2499
2500 // Disalow further properties to be added to the object.
2501 MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
2502 Handle<JSObject> object);
2503
2504 // ES5 Object.freeze
2505 MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
2506
2507 // Called the first time an object is observed with ES7 Object.observe.
2508 static void SetObserved(Handle<JSObject> object);
2509
2510 // Copy object.
2511 enum DeepCopyHints {
2512 kNoHints = 0,
2513 kObjectIsShallowArray = 1
2514 };
2515
2516 static Handle<JSObject> Copy(Handle<JSObject> object);
2517 MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
2518 Handle<JSObject> object,
2519 AllocationSiteUsageContext* site_context,
2520 DeepCopyHints hints = kNoHints);
2521 MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
2522 Handle<JSObject> object,
2523 AllocationSiteCreationContext* site_context);
2524
2525 static Handle<Object> GetDataProperty(Handle<JSObject> object,
2526 Handle<Name> key);
2527
2528 // Casting.
2529 static inline JSObject* cast(Object* obj);
2530
2531 // Dispatched behavior.
2532 void JSObjectShortPrint(StringStream* accumulator);
2533 DECLARE_PRINTER(JSObject)
2534 DECLARE_VERIFIER(JSObject)
2535 #ifdef OBJECT_PRINT
2536 void PrintProperties(FILE* out = stdout);
2537 void PrintElements(FILE* out = stdout);
2538 void PrintTransitions(FILE* out = stdout);
2539 #endif
2540
2541 static void PrintElementsTransition(
2542 FILE* file, Handle<JSObject> object,
2543 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2544 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2545
2546 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
2547
2548 #ifdef DEBUG
2549 // Structure for collecting spill information about JSObjects.
2550 class SpillInformation {
2551 public:
2552 void Clear();
2553 void Print();
2554 int number_of_objects_;
2555 int number_of_objects_with_fast_properties_;
2556 int number_of_objects_with_fast_elements_;
2557 int number_of_fast_used_fields_;
2558 int number_of_fast_unused_fields_;
2559 int number_of_slow_used_properties_;
2560 int number_of_slow_unused_properties_;
2561 int number_of_fast_used_elements_;
2562 int number_of_fast_unused_elements_;
2563 int number_of_slow_used_elements_;
2564 int number_of_slow_unused_elements_;
2565 };
2566
2567 void IncrementSpillStatistics(SpillInformation* info);
2568 #endif
2569
2570 #ifdef VERIFY_HEAP
2571 // If a GC was caused while constructing this object, the elements pointer
2572 // may point to a one pointer filler map. The object won't be rooted, but
2573 // our heap verification code could stumble across it.
2574 bool ElementsAreSafeToExamine();
2575 #endif
2576
2577 Object* SlowReverseLookup(Object* value);
2578
2579 // Maximal number of fast properties for the JSObject. Used to
2580 // restrict the number of map transitions to avoid an explosion in
2581 // the number of maps for objects used as dictionaries.
2582 inline bool TooManyFastProperties(
2583 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
2584
2585 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2586 // Also maximal value of JSArray's length property.
2587 static const uint32_t kMaxElementCount = 0xffffffffu;
2588
2589 // Constants for heuristics controlling conversion of fast elements
2590 // to slow elements.
2591
2592 // Maximal gap that can be introduced by adding an element beyond
2593 // the current elements length.
2594 static const uint32_t kMaxGap = 1024;
2595
2596 // Maximal length of fast elements array that won't be checked for
2597 // being dense enough on expansion.
2598 static const int kMaxUncheckedFastElementsLength = 5000;
2599
2600 // Same as above but for old arrays. This limit is more strict. We
2601 // don't want to be wasteful with long lived objects.
2602 static const int kMaxUncheckedOldFastElementsLength = 500;
2603
2604 // Note that Page::kMaxRegularHeapObjectSize puts a limit on
2605 // permissible values (see the ASSERT in heap.cc).
2606 static const int kInitialMaxFastElementArray = 100000;
2607
2608 // This constant applies only to the initial map of "$Object" aka
2609 // "global.Object" and not to arbitrary other JSObject maps.
2610 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2611
2612 static const int kFastPropertiesSoftLimit = 12;
2613 static const int kMaxFastProperties = 128;
2614 static const int kMaxInstanceSize = 255 * kPointerSize;
2615 // When extending the backing storage for property values, we increase
2616 // its size by more than the 1 entry necessary, so sequentially adding fields
2617 // to the same object requires fewer allocations and copies.
2618 static const int kFieldsAdded = 3;
2619
2620 // Layout description.
2621 static const int kPropertiesOffset = HeapObject::kHeaderSize;
2622 static const int kElementsOffset = kPropertiesOffset + kPointerSize;
2623 static const int kHeaderSize = kElementsOffset + kPointerSize;
2624
2625 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
2626
2627 class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
2628 public:
2629 static inline int SizeOf(Map* map, HeapObject* object);
2630 };
2631
2632 Context* GetCreationContext();
2633
2634 // Enqueue change record for Object.observe. May cause GC.
2635 static void EnqueueChangeRecord(Handle<JSObject> object,
2636 const char* type,
2637 Handle<Name> name,
2638 Handle<Object> old_value);
2639
2640 private:
2641 friend class DictionaryElementsAccessor;
2642 friend class JSReceiver;
2643 friend class Object;
2644
2645 static void UpdateAllocationSite(Handle<JSObject> object,
2646 ElementsKind to_kind);
2647
2648 // Used from Object::GetProperty().
2649 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2650 LookupIterator* it);
2651
2652 MUST_USE_RESULT static MaybeHandle<Object> GetElementWithCallback(
2653 Handle<JSObject> object,
2654 Handle<Object> receiver,
2655 Handle<Object> structure,
2656 uint32_t index,
2657 Handle<Object> holder);
2658
2659 static PropertyAttributes GetElementAttributeWithInterceptor(
2660 Handle<JSObject> object,
2661 Handle<JSReceiver> receiver,
2662 uint32_t index,
2663 bool continue_search);
2664 static PropertyAttributes GetElementAttributeWithoutInterceptor(
2665 Handle<JSObject> object,
2666 Handle<JSReceiver> receiver,
2667 uint32_t index,
2668 bool continue_search);
2669 MUST_USE_RESULT static MaybeHandle<Object> SetElementWithCallback(
2670 Handle<JSObject> object,
2671 Handle<Object> structure,
2672 uint32_t index,
2673 Handle<Object> value,
2674 Handle<JSObject> holder,
2675 StrictMode strict_mode);
2676 MUST_USE_RESULT static MaybeHandle<Object> SetElementWithInterceptor(
2677 Handle<JSObject> object,
2678 uint32_t index,
2679 Handle<Object> value,
2680 PropertyAttributes attributes,
2681 StrictMode strict_mode,
2682 bool check_prototype,
2683 SetPropertyMode set_mode);
2684 MUST_USE_RESULT static MaybeHandle<Object> SetElementWithoutInterceptor(
2685 Handle<JSObject> object,
2686 uint32_t index,
2687 Handle<Object> value,
2688 PropertyAttributes attributes,
2689 StrictMode strict_mode,
2690 bool check_prototype,
2691 SetPropertyMode set_mode);
2692 MUST_USE_RESULT
2693 static MaybeHandle<Object> SetElementWithCallbackSetterInPrototypes(
2694 Handle<JSObject> object,
2695 uint32_t index,
2696 Handle<Object> value,
2697 bool* found,
2698 StrictMode strict_mode);
2699 MUST_USE_RESULT static MaybeHandle<Object> SetDictionaryElement(
2700 Handle<JSObject> object,
2701 uint32_t index,
2702 Handle<Object> value,
2703 PropertyAttributes attributes,
2704 StrictMode strict_mode,
2705 bool check_prototype,
2706 SetPropertyMode set_mode = SET_PROPERTY);
2707 MUST_USE_RESULT static MaybeHandle<Object> SetFastDoubleElement(
2708 Handle<JSObject> object,
2709 uint32_t index,
2710 Handle<Object> value,
2711 StrictMode strict_mode,
2712 bool check_prototype = true);
2713
2714 // Searches the prototype chain for property 'name'. If it is found and
2715 // has a setter, invoke it and set '*done' to true. If it is found and is
2716 // read-only, reject and set '*done' to true. Otherwise, set '*done' to
2717 // false. Can throw and return an empty handle with '*done==true'.
2718 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyViaPrototypes(
2719 Handle<JSObject> object,
2720 Handle<Name> name,
2721 Handle<Object> value,
2722 PropertyAttributes attributes,
2723 StrictMode strict_mode,
2724 bool* done);
2725 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyPostInterceptor(
2726 Handle<JSObject> object,
2727 Handle<Name> name,
2728 Handle<Object> value,
2729 PropertyAttributes attributes,
2730 StrictMode strict_mode);
2731 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyUsingTransition(
2732 Handle<JSObject> object,
2733 LookupResult* lookup,
2734 Handle<Name> name,
2735 Handle<Object> value,
2736 PropertyAttributes attributes);
2737 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
2738 Handle<JSObject> object,
2739 LookupResult* result,
2740 Handle<Name> name,
2741 Handle<Object> value,
2742 bool check_prototype,
2743 StrictMode strict_mode);
2744
2745 // Add a property to an object.
2746 MUST_USE_RESULT static MaybeHandle<Object> AddProperty(
2747 Handle<JSObject> object,
2748 Handle<Name> name,
2749 Handle<Object> value,
2750 PropertyAttributes attributes,
2751 StrictMode strict_mode,
2752 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
2753 ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
2754 ValueType value_type = OPTIMAL_REPRESENTATION,
2755 StoreMode mode = ALLOW_AS_CONSTANT,
2756 TransitionFlag flag = INSERT_TRANSITION);
2757
2758 // Add a property to a fast-case object.
2759 static void AddFastProperty(Handle<JSObject> object,
2760 Handle<Name> name,
2761 Handle<Object> value,
2762 PropertyAttributes attributes,
2763 StoreFromKeyed store_mode,
2764 ValueType value_type,
2765 TransitionFlag flag);
2766
2767 static void MigrateToNewProperty(Handle<JSObject> object,
2768 Handle<Map> transition,
2769 Handle<Object> value);
2770
2771 // Add a property to a slow-case object.
2772 static void AddSlowProperty(Handle<JSObject> object,
2773 Handle<Name> name,
2774 Handle<Object> value,
2775 PropertyAttributes attributes);
2776
2777 MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
2778 Handle<JSObject> object,
2779 Handle<Name> name,
2780 DeleteMode mode);
2781 static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
2782 Handle<Name> name,
2783 DeleteMode mode);
2784 MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
2785 Handle<JSObject> object,
2786 Handle<Name> name);
2787
2788 // Deletes the named property in a normalized object.
2789 static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
2790 Handle<Name> name,
2791 DeleteMode mode);
2792
2793 MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
2794 Handle<JSObject> object,
2795 uint32_t index,
2796 DeleteMode mode);
2797 MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithInterceptor(
2798 Handle<JSObject> object,
2799 uint32_t index);
2800
2801 bool ReferencesObjectFromElements(FixedArray* elements,
2802 ElementsKind kind,
2803 Object* object);
2804
2805 // Returns true if most of the elements backing storage is used.
2806 bool HasDenseElements();
2807
2808 // Gets the current elements capacity and the number of used elements.
2809 void GetElementsCapacityAndUsage(int* capacity, int* used);
2810
2811 static bool CanSetCallback(Handle<JSObject> object, Handle<Name> name);
2812 static void SetElementCallback(Handle<JSObject> object,
2813 uint32_t index,
2814 Handle<Object> structure,
2815 PropertyAttributes attributes);
2816 static void SetPropertyCallback(Handle<JSObject> object,
2817 Handle<Name> name,
2818 Handle<Object> structure,
2819 PropertyAttributes attributes);
2820 static void DefineElementAccessor(Handle<JSObject> object,
2821 uint32_t index,
2822 Handle<Object> getter,
2823 Handle<Object> setter,
2824 PropertyAttributes attributes,
2825 v8::AccessControl access_control);
2826 static Handle<AccessorPair> CreateAccessorPairFor(Handle<JSObject> object,
2827 Handle<Name> name);
2828 static void DefinePropertyAccessor(Handle<JSObject> object,
2829 Handle<Name> name,
2830 Handle<Object> getter,
2831 Handle<Object> setter,
2832 PropertyAttributes attributes,
2833 v8::AccessControl access_control);
2834
2835 // Try to define a single accessor paying attention to map transitions.
2836 // Returns false if this was not possible and we have to use the slow case.
2837 static bool DefineFastAccessor(Handle<JSObject> object,
2838 Handle<Name> name,
2839 AccessorComponent component,
2840 Handle<Object> accessor,
2841 PropertyAttributes attributes);
2842
2843
2844 // Return the hash table backing store or the inline stored identity hash,
2845 // whatever is found.
2846 MUST_USE_RESULT Object* GetHiddenPropertiesHashTable();
2847
2848 // Return the hash table backing store for hidden properties. If there is no
2849 // backing store, allocate one.
2850 static Handle<ObjectHashTable> GetOrCreateHiddenPropertiesHashtable(
2851 Handle<JSObject> object);
2852
2853 // Set the hidden property backing store to either a hash table or
2854 // the inline-stored identity hash.
2855 static Handle<Object> SetHiddenPropertiesHashTable(
2856 Handle<JSObject> object,
2857 Handle<Object> value);
2858
2859 MUST_USE_RESULT Object* GetIdentityHash();
2860
2861 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
2862
2863 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2864 };
2865
2866
2867 // Common superclass for FixedArrays that allow implementations to share
2868 // common accessors and some code paths.
2869 class FixedArrayBase: public HeapObject {
2870 public:
2871 // [length]: length of the array.
2872 inline int length();
2873 inline void set_length(int value);
2874
2875 // Get and set the length using acquire loads and release stores.
2876 inline int synchronized_length();
2877 inline void synchronized_set_length(int value);
2878
2879 inline static FixedArrayBase* cast(Object* object);
2880
2881 // Layout description.
2882 // Length is smi tagged when it is stored.
2883 static const int kLengthOffset = HeapObject::kHeaderSize;
2884 static const int kHeaderSize = kLengthOffset + kPointerSize;
2885 };
2886
2887
2888 class FixedDoubleArray;
2889 class IncrementalMarking;
2890
2891
2892 // FixedArray describes fixed-sized arrays with element type Object*.
2893 class FixedArray: public FixedArrayBase {
2894 public:
2895 // Setter and getter for elements.
2896 inline Object* get(int index);
2897 static inline Handle<Object> get(Handle<FixedArray> array, int index);
2898 // Setter that uses write barrier.
2899 inline void set(int index, Object* value);
2900 inline bool is_the_hole(int index);
2901
2902 // Setter that doesn't need write barrier.
2903 inline void set(int index, Smi* value);
2904 // Setter with explicit barrier mode.
2905 inline void set(int index, Object* value, WriteBarrierMode mode);
2906
2907 // Setters for frequently used oddballs located in old space.
2908 inline void set_undefined(int index);
2909 inline void set_null(int index);
2910 inline void set_the_hole(int index);
2911
2912 inline Object** GetFirstElementAddress();
2913 inline bool ContainsOnlySmisOrHoles();
2914
2915 // Gives access to raw memory which stores the array's data.
2916 inline Object** data_start();
2917
2918 inline void FillWithHoles(int from, int to);
2919
2920 // Shrink length and insert filler objects.
2921 void Shrink(int length);
2922
2923 // Copy operation.
2924 static Handle<FixedArray> CopySize(Handle<FixedArray> array,
2925 int new_length,
2926 PretenureFlag pretenure = NOT_TENURED);
2927
2928 // Add the elements of a JSArray to this FixedArray.
2929 MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike(
2930 Handle<FixedArray> content,
2931 Handle<JSObject> array);
2932
2933 // Computes the union of keys and return the result.
2934 // Used for implementing "for (n in object) { }"
2935 MUST_USE_RESULT static MaybeHandle<FixedArray> UnionOfKeys(
2936 Handle<FixedArray> first,
2937 Handle<FixedArray> second);
2938
2939 // Copy a sub array from the receiver to dest.
2940 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2941
2942 // Garbage collection support.
SizeFor(int length)2943 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2944
2945 // Code Generation support.
OffsetOfElementAt(int index)2946 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2947
2948 // Garbage collection support.
RawFieldOfElementAt(int index)2949 Object** RawFieldOfElementAt(int index) {
2950 return HeapObject::RawField(this, OffsetOfElementAt(index));
2951 }
2952
2953 // Casting.
2954 static inline FixedArray* cast(Object* obj);
2955
2956 // Maximal allowed size, in bytes, of a single FixedArray.
2957 // Prevents overflowing size computations, as well as extreme memory
2958 // consumption.
2959 static const int kMaxSize = 128 * MB * kPointerSize;
2960 // Maximally allowed length of a FixedArray.
2961 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
2962
2963 // Dispatched behavior.
2964 DECLARE_PRINTER(FixedArray)
2965 DECLARE_VERIFIER(FixedArray)
2966 #ifdef DEBUG
2967 // Checks if two FixedArrays have identical contents.
2968 bool IsEqualTo(FixedArray* other);
2969 #endif
2970
2971 // Swap two elements in a pair of arrays. If this array and the
2972 // numbers array are the same object, the elements are only swapped
2973 // once.
2974 void SwapPairs(FixedArray* numbers, int i, int j);
2975
2976 // Sort prefix of this array and the numbers array as pairs wrt. the
2977 // numbers. If the numbers array and the this array are the same
2978 // object, the prefix of this array is sorted.
2979 void SortPairs(FixedArray* numbers, uint32_t len);
2980
2981 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
2982 public:
SizeOf(Map * map,HeapObject * object)2983 static inline int SizeOf(Map* map, HeapObject* object) {
2984 return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
2985 }
2986 };
2987
2988 protected:
2989 // Set operation on FixedArray without using write barriers. Can
2990 // only be used for storing old space objects or smis.
2991 static inline void NoWriteBarrierSet(FixedArray* array,
2992 int index,
2993 Object* value);
2994
2995 // Set operation on FixedArray without incremental write barrier. Can
2996 // only be used if the object is guaranteed to be white (whiteness witness
2997 // is present).
2998 static inline void NoIncrementalWriteBarrierSet(FixedArray* array,
2999 int index,
3000 Object* value);
3001
3002 private:
3003 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
3004
3005 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
3006 };
3007
3008
3009 // FixedDoubleArray describes fixed-sized arrays with element type double.
3010 class FixedDoubleArray: public FixedArrayBase {
3011 public:
3012 // Setter and getter for elements.
3013 inline double get_scalar(int index);
3014 inline int64_t get_representation(int index);
3015 static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
3016 inline void set(int index, double value);
3017 inline void set_the_hole(int index);
3018
3019 // Checking for the hole.
3020 inline bool is_the_hole(int index);
3021
3022 // Garbage collection support.
SizeFor(int length)3023 inline static int SizeFor(int length) {
3024 return kHeaderSize + length * kDoubleSize;
3025 }
3026
3027 // Gives access to raw memory which stores the array's data.
3028 inline double* data_start();
3029
3030 inline void FillWithHoles(int from, int to);
3031
3032 // Code Generation support.
OffsetOfElementAt(int index)3033 static int OffsetOfElementAt(int index) { return SizeFor(index); }
3034
3035 inline static bool is_the_hole_nan(double value);
3036 inline static double hole_nan_as_double();
3037 inline static double canonical_not_the_hole_nan_as_double();
3038
3039 // Casting.
3040 static inline FixedDoubleArray* cast(Object* obj);
3041
3042 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
3043 // Prevents overflowing size computations, as well as extreme memory
3044 // consumption.
3045 static const int kMaxSize = 512 * MB;
3046 // Maximally allowed length of a FixedArray.
3047 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
3048
3049 // Dispatched behavior.
3050 DECLARE_PRINTER(FixedDoubleArray)
3051 DECLARE_VERIFIER(FixedDoubleArray)
3052
3053 private:
3054 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
3055 };
3056
3057
3058 // ConstantPoolArray describes a fixed-sized array containing constant pool
3059 // entries.
3060 //
3061 // A ConstantPoolArray can be structured in two different ways depending upon
3062 // whether it is extended or small. The is_extended_layout() method can be used
3063 // to discover which layout the constant pool has.
3064 //
3065 // The format of a small constant pool is:
3066 // [kSmallLayout1Offset] : Small section layout bitmap 1
3067 // [kSmallLayout2Offset] : Small section layout bitmap 2
3068 // [first_index(INT64, SMALL_SECTION)] : 64 bit entries
3069 // ... : ...
3070 // [first_index(CODE_PTR, SMALL_SECTION)] : code pointer entries
3071 // ... : ...
3072 // [first_index(HEAP_PTR, SMALL_SECTION)] : heap pointer entries
3073 // ... : ...
3074 // [first_index(INT32, SMALL_SECTION)] : 32 bit entries
3075 // ... : ...
3076 //
3077 // If the constant pool has an extended layout, the extended section constant
3078 // pool also contains an extended section, which has the following format at
3079 // location get_extended_section_header_offset():
3080 // [kExtendedInt64CountOffset] : count of extended 64 bit entries
3081 // [kExtendedCodePtrCountOffset] : count of extended code pointers
3082 // [kExtendedHeapPtrCountOffset] : count of extended heap pointers
3083 // [kExtendedInt32CountOffset] : count of extended 32 bit entries
3084 // [first_index(INT64, EXTENDED_SECTION)] : 64 bit entries
3085 // ... : ...
3086 // [first_index(CODE_PTR, EXTENDED_SECTION)]: code pointer entries
3087 // ... : ...
3088 // [first_index(HEAP_PTR, EXTENDED_SECTION)]: heap pointer entries
3089 // ... : ...
3090 // [first_index(INT32, EXTENDED_SECTION)] : 32 bit entries
3091 // ... : ...
3092 //
3093 class ConstantPoolArray: public HeapObject {
3094 public:
3095 enum WeakObjectState {
3096 NO_WEAK_OBJECTS,
3097 WEAK_OBJECTS_IN_OPTIMIZED_CODE,
3098 WEAK_OBJECTS_IN_IC
3099 };
3100
3101 enum Type {
3102 INT64 = 0,
3103 CODE_PTR,
3104 HEAP_PTR,
3105 INT32,
3106 // Number of types stored by the ConstantPoolArrays.
3107 NUMBER_OF_TYPES,
3108 FIRST_TYPE = INT64,
3109 LAST_TYPE = INT32
3110 };
3111
3112 enum LayoutSection {
3113 SMALL_SECTION = 0,
3114 EXTENDED_SECTION
3115 };
3116
3117 class NumberOfEntries BASE_EMBEDDED {
3118 public:
NumberOfEntries(int int64_count,int code_ptr_count,int heap_ptr_count,int int32_count)3119 inline NumberOfEntries(int int64_count, int code_ptr_count,
3120 int heap_ptr_count, int int32_count) {
3121 element_counts_[INT64] = int64_count;
3122 element_counts_[CODE_PTR] = code_ptr_count;
3123 element_counts_[HEAP_PTR] = heap_ptr_count;
3124 element_counts_[INT32] = int32_count;
3125 }
3126
NumberOfEntries(ConstantPoolArray * array,LayoutSection section)3127 inline NumberOfEntries(ConstantPoolArray* array, LayoutSection section) {
3128 element_counts_[INT64] = array->number_of_entries(INT64, section);
3129 element_counts_[CODE_PTR] = array->number_of_entries(CODE_PTR, section);
3130 element_counts_[HEAP_PTR] = array->number_of_entries(HEAP_PTR, section);
3131 element_counts_[INT32] = array->number_of_entries(INT32, section);
3132 }
3133
count_of(Type type)3134 inline int count_of(Type type) const {
3135 ASSERT(type < NUMBER_OF_TYPES);
3136 return element_counts_[type];
3137 }
3138
total_count()3139 inline int total_count() const {
3140 int count = 0;
3141 for (int i = 0; i < NUMBER_OF_TYPES; i++) {
3142 count += element_counts_[i];
3143 }
3144 return count;
3145 }
3146
are_in_range(int min,int max)3147 inline int are_in_range(int min, int max) const {
3148 for (int i = FIRST_TYPE; i < NUMBER_OF_TYPES; i++) {
3149 if (element_counts_[i] < min || element_counts_[i] > max) {
3150 return false;
3151 }
3152 }
3153 return true;
3154 }
3155
3156 private:
3157 int element_counts_[NUMBER_OF_TYPES];
3158 };
3159
3160 class Iterator BASE_EMBEDDED {
3161 public:
Iterator(ConstantPoolArray * array,Type type)3162 inline Iterator(ConstantPoolArray* array, Type type)
3163 : array_(array), type_(type), final_section_(array->final_section()) {
3164 current_section_ = SMALL_SECTION;
3165 next_index_ = array->first_index(type, SMALL_SECTION);
3166 update_section();
3167 }
3168
3169 inline int next_index();
3170 inline bool is_finished();
3171 private:
3172 inline void update_section();
3173 ConstantPoolArray* array_;
3174 const Type type_;
3175 const LayoutSection final_section_;
3176
3177 LayoutSection current_section_;
3178 int next_index_;
3179 };
3180
3181 // Getters for the first index, the last index and the count of entries of
3182 // a given type for a given layout section.
3183 inline int first_index(Type type, LayoutSection layout_section);
3184 inline int last_index(Type type, LayoutSection layout_section);
3185 inline int number_of_entries(Type type, LayoutSection layout_section);
3186
3187 // Returns the type of the entry at the given index.
3188 inline Type get_type(int index);
3189
3190 // Setter and getter for pool elements.
3191 inline Address get_code_ptr_entry(int index);
3192 inline Object* get_heap_ptr_entry(int index);
3193 inline int64_t get_int64_entry(int index);
3194 inline int32_t get_int32_entry(int index);
3195 inline double get_int64_entry_as_double(int index);
3196
3197 inline void set(int index, Address value);
3198 inline void set(int index, Object* value);
3199 inline void set(int index, int64_t value);
3200 inline void set(int index, double value);
3201 inline void set(int index, int32_t value);
3202
3203 // Setter and getter for weak objects state
3204 inline void set_weak_object_state(WeakObjectState state);
3205 inline WeakObjectState get_weak_object_state();
3206
3207 // Returns true if the constant pool has an extended layout, false if it has
3208 // only the small layout.
3209 inline bool is_extended_layout();
3210
3211 // Returns the last LayoutSection in this constant pool array.
3212 inline LayoutSection final_section();
3213
3214 // Set up initial state for a small layout constant pool array.
3215 inline void Init(const NumberOfEntries& small);
3216
3217 // Set up initial state for an extended layout constant pool array.
3218 inline void InitExtended(const NumberOfEntries& small,
3219 const NumberOfEntries& extended);
3220
3221 // Clears the pointer entries with GC safe values.
3222 void ClearPtrEntries(Isolate* isolate);
3223
3224 // returns the total number of entries in the constant pool array.
3225 inline int length();
3226
3227 // Garbage collection support.
3228 inline int size();
3229
SizeFor(const NumberOfEntries & small)3230 inline static int SizeFor(const NumberOfEntries& small) {
3231 int size = kFirstEntryOffset +
3232 (small.count_of(INT64) * kInt64Size) +
3233 (small.count_of(CODE_PTR) * kPointerSize) +
3234 (small.count_of(HEAP_PTR) * kPointerSize) +
3235 (small.count_of(INT32) * kInt32Size);
3236 return RoundUp(size, kPointerSize);
3237 }
3238
SizeForExtended(const NumberOfEntries & small,const NumberOfEntries & extended)3239 inline static int SizeForExtended(const NumberOfEntries& small,
3240 const NumberOfEntries& extended) {
3241 int size = SizeFor(small);
3242 size = RoundUp(size, kInt64Size); // Align extended header to 64 bits.
3243 size += kExtendedFirstOffset +
3244 (extended.count_of(INT64) * kInt64Size) +
3245 (extended.count_of(CODE_PTR) * kPointerSize) +
3246 (extended.count_of(HEAP_PTR) * kPointerSize) +
3247 (extended.count_of(INT32) * kInt32Size);
3248 return RoundUp(size, kPointerSize);
3249 }
3250
entry_size(Type type)3251 inline static int entry_size(Type type) {
3252 switch (type) {
3253 case INT32:
3254 return kInt32Size;
3255 case INT64:
3256 return kInt64Size;
3257 case CODE_PTR:
3258 case HEAP_PTR:
3259 return kPointerSize;
3260 default:
3261 UNREACHABLE();
3262 return 0;
3263 }
3264 }
3265
3266 // Code Generation support.
OffsetOfElementAt(int index)3267 inline int OffsetOfElementAt(int index) {
3268 int offset;
3269 LayoutSection section;
3270 if (is_extended_layout() && index >= first_extended_section_index()) {
3271 section = EXTENDED_SECTION;
3272 offset = get_extended_section_header_offset() + kExtendedFirstOffset;
3273 } else {
3274 section = SMALL_SECTION;
3275 offset = kFirstEntryOffset;
3276 }
3277
3278 // Add offsets for the preceding type sections.
3279 ASSERT(index <= last_index(LAST_TYPE, section));
3280 for (Type type = FIRST_TYPE; index > last_index(type, section);
3281 type = next_type(type)) {
3282 offset += entry_size(type) * number_of_entries(type, section);
3283 }
3284
3285 // Add offset for the index in it's type.
3286 Type type = get_type(index);
3287 offset += entry_size(type) * (index - first_index(type, section));
3288 return offset;
3289 }
3290
3291 // Casting.
3292 static inline ConstantPoolArray* cast(Object* obj);
3293
3294 // Garbage collection support.
RawFieldOfElementAt(int index)3295 Object** RawFieldOfElementAt(int index) {
3296 return HeapObject::RawField(this, OffsetOfElementAt(index));
3297 }
3298
3299 // Small Layout description.
3300 static const int kSmallLayout1Offset = HeapObject::kHeaderSize;
3301 static const int kSmallLayout2Offset = kSmallLayout1Offset + kInt32Size;
3302 static const int kHeaderSize = kSmallLayout2Offset + kInt32Size;
3303 static const int kFirstEntryOffset = ROUND_UP(kHeaderSize, kInt64Size);
3304
3305 static const int kSmallLayoutCountBits = 10;
3306 static const int kMaxSmallEntriesPerType = (1 << kSmallLayoutCountBits) - 1;
3307
3308 // Fields in kSmallLayout1Offset.
3309 class Int64CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
3310 class CodePtrCountField: public BitField<int, 11, kSmallLayoutCountBits> {};
3311 class HeapPtrCountField: public BitField<int, 21, kSmallLayoutCountBits> {};
3312 class IsExtendedField: public BitField<bool, 31, 1> {};
3313
3314 // Fields in kSmallLayout2Offset.
3315 class Int32CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
3316 class TotalCountField: public BitField<int, 11, 12> {};
3317 class WeakObjectStateField: public BitField<WeakObjectState, 23, 2> {};
3318
3319 // Extended layout description, which starts at
3320 // get_extended_section_header_offset().
3321 static const int kExtendedInt64CountOffset = 0;
3322 static const int kExtendedCodePtrCountOffset =
3323 kExtendedInt64CountOffset + kPointerSize;
3324 static const int kExtendedHeapPtrCountOffset =
3325 kExtendedCodePtrCountOffset + kPointerSize;
3326 static const int kExtendedInt32CountOffset =
3327 kExtendedHeapPtrCountOffset + kPointerSize;
3328 static const int kExtendedFirstOffset =
3329 kExtendedInt32CountOffset + kPointerSize;
3330
3331 // Dispatched behavior.
3332 void ConstantPoolIterateBody(ObjectVisitor* v);
3333
3334 DECLARE_PRINTER(ConstantPoolArray)
3335 DECLARE_VERIFIER(ConstantPoolArray)
3336
3337 private:
3338 inline int first_extended_section_index();
3339 inline int get_extended_section_header_offset();
3340
next_type(Type type)3341 inline static Type next_type(Type type) {
3342 ASSERT(type >= FIRST_TYPE && type < NUMBER_OF_TYPES);
3343 int type_int = static_cast<int>(type);
3344 return static_cast<Type>(++type_int);
3345 }
3346
3347 DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
3348 };
3349
3350
3351 // DescriptorArrays are fixed arrays used to hold instance descriptors.
3352 // The format of the these objects is:
3353 // [0]: Number of descriptors
3354 // [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
3355 // [0]: pointer to fixed array with enum cache
3356 // [1]: either Smi(0) or pointer to fixed array with indices
3357 // [2]: first key
3358 // [2 + number of descriptors * kDescriptorSize]: start of slack
3359 class DescriptorArray: public FixedArray {
3360 public:
3361 // Returns true for both shared empty_descriptor_array and for smis, which the
3362 // map uses to encode additional bit fields when the descriptor array is not
3363 // yet used.
3364 inline bool IsEmpty();
3365
3366 // Returns the number of descriptors in the array.
number_of_descriptors()3367 int number_of_descriptors() {
3368 ASSERT(length() >= kFirstIndex || IsEmpty());
3369 int len = length();
3370 return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
3371 }
3372
number_of_descriptors_storage()3373 int number_of_descriptors_storage() {
3374 int len = length();
3375 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
3376 }
3377
NumberOfSlackDescriptors()3378 int NumberOfSlackDescriptors() {
3379 return number_of_descriptors_storage() - number_of_descriptors();
3380 }
3381
3382 inline void SetNumberOfDescriptors(int number_of_descriptors);
number_of_entries()3383 inline int number_of_entries() { return number_of_descriptors(); }
3384
HasEnumCache()3385 bool HasEnumCache() {
3386 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
3387 }
3388
CopyEnumCacheFrom(DescriptorArray * array)3389 void CopyEnumCacheFrom(DescriptorArray* array) {
3390 set(kEnumCacheIndex, array->get(kEnumCacheIndex));
3391 }
3392
GetEnumCache()3393 FixedArray* GetEnumCache() {
3394 ASSERT(HasEnumCache());
3395 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
3396 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
3397 }
3398
HasEnumIndicesCache()3399 bool HasEnumIndicesCache() {
3400 if (IsEmpty()) return false;
3401 Object* object = get(kEnumCacheIndex);
3402 if (object->IsSmi()) return false;
3403 FixedArray* bridge = FixedArray::cast(object);
3404 return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
3405 }
3406
GetEnumIndicesCache()3407 FixedArray* GetEnumIndicesCache() {
3408 ASSERT(HasEnumIndicesCache());
3409 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
3410 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
3411 }
3412
GetEnumCacheSlot()3413 Object** GetEnumCacheSlot() {
3414 ASSERT(HasEnumCache());
3415 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
3416 kEnumCacheOffset);
3417 }
3418
3419 void ClearEnumCache();
3420
3421 // Initialize or change the enum cache,
3422 // using the supplied storage for the small "bridge".
3423 void SetEnumCache(FixedArray* bridge_storage,
3424 FixedArray* new_cache,
3425 Object* new_index_cache);
3426
3427 // Accessors for fetching instance descriptor at descriptor number.
3428 inline Name* GetKey(int descriptor_number);
3429 inline Object** GetKeySlot(int descriptor_number);
3430 inline Object* GetValue(int descriptor_number);
3431 inline void SetValue(int descriptor_number, Object* value);
3432 inline Object** GetValueSlot(int descriptor_number);
3433 inline Object** GetDescriptorStartSlot(int descriptor_number);
3434 inline Object** GetDescriptorEndSlot(int descriptor_number);
3435 inline PropertyDetails GetDetails(int descriptor_number);
3436 inline PropertyType GetType(int descriptor_number);
3437 inline int GetFieldIndex(int descriptor_number);
3438 inline HeapType* GetFieldType(int descriptor_number);
3439 inline Object* GetConstant(int descriptor_number);
3440 inline Object* GetCallbacksObject(int descriptor_number);
3441 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
3442
3443 inline Name* GetSortedKey(int descriptor_number);
3444 inline int GetSortedKeyIndex(int descriptor_number);
3445 inline void SetSortedKey(int pointer, int descriptor_number);
3446 inline void SetRepresentation(int descriptor_number,
3447 Representation representation);
3448
3449 // Accessor for complete descriptor.
3450 inline void Get(int descriptor_number, Descriptor* desc);
3451 inline void Set(int descriptor_number, Descriptor* desc);
3452 void Replace(int descriptor_number, Descriptor* descriptor);
3453
3454 // Append automatically sets the enumeration index. This should only be used
3455 // to add descriptors in bulk at the end, followed by sorting the descriptor
3456 // array.
3457 inline void Append(Descriptor* desc);
3458
3459 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
3460 int enumeration_index,
3461 int slack = 0);
3462
3463 static Handle<DescriptorArray> CopyUpToAddAttributes(
3464 Handle<DescriptorArray> desc,
3465 int enumeration_index,
3466 PropertyAttributes attributes,
3467 int slack = 0);
3468
3469 // Sort the instance descriptors by the hash codes of their keys.
3470 void Sort();
3471
3472 // Search the instance descriptors for given name.
3473 INLINE(int Search(Name* name, int number_of_own_descriptors));
3474
3475 // As the above, but uses DescriptorLookupCache and updates it when
3476 // necessary.
3477 INLINE(int SearchWithCache(Name* name, Map* map));
3478
3479 // Allocates a DescriptorArray, but returns the singleton
3480 // empty descriptor array object if number_of_descriptors is 0.
3481 static Handle<DescriptorArray> Allocate(Isolate* isolate,
3482 int number_of_descriptors,
3483 int slack = 0);
3484
3485 // Casting.
3486 static inline DescriptorArray* cast(Object* obj);
3487
3488 // Constant for denoting key was not found.
3489 static const int kNotFound = -1;
3490
3491 static const int kDescriptorLengthIndex = 0;
3492 static const int kEnumCacheIndex = 1;
3493 static const int kFirstIndex = 2;
3494
3495 // The length of the "bridge" to the enum cache.
3496 static const int kEnumCacheBridgeLength = 2;
3497 static const int kEnumCacheBridgeCacheIndex = 0;
3498 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
3499
3500 // Layout description.
3501 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
3502 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
3503 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
3504
3505 // Layout description for the bridge array.
3506 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
3507
3508 // Layout of descriptor.
3509 static const int kDescriptorKey = 0;
3510 static const int kDescriptorDetails = 1;
3511 static const int kDescriptorValue = 2;
3512 static const int kDescriptorSize = 3;
3513
3514 #ifdef OBJECT_PRINT
3515 // Print all the descriptors.
3516 void PrintDescriptors(FILE* out = stdout);
3517 #endif
3518
3519 #ifdef DEBUG
3520 // Is the descriptor array sorted and without duplicates?
3521 bool IsSortedNoDuplicates(int valid_descriptors = -1);
3522
3523 // Is the descriptor array consistent with the back pointers in targets?
3524 bool IsConsistentWithBackPointers(Map* current_map);
3525
3526 // Are two DescriptorArrays equal?
3527 bool IsEqualTo(DescriptorArray* other);
3528 #endif
3529
3530 // Returns the fixed array length required to hold number_of_descriptors
3531 // descriptors.
LengthFor(int number_of_descriptors)3532 static int LengthFor(int number_of_descriptors) {
3533 return ToKeyIndex(number_of_descriptors);
3534 }
3535
3536 private:
3537 // WhitenessWitness is used to prove that a descriptor array is white
3538 // (unmarked), so incremental write barriers can be skipped because the
3539 // marking invariant cannot be broken and slots pointing into evacuation
3540 // candidates will be discovered when the object is scanned. A witness is
3541 // always stack-allocated right after creating an array. By allocating a
3542 // witness, incremental marking is globally disabled. The witness is then
3543 // passed along wherever needed to statically prove that the array is known to
3544 // be white.
3545 class WhitenessWitness {
3546 public:
3547 inline explicit WhitenessWitness(DescriptorArray* array);
3548 inline ~WhitenessWitness();
3549
3550 private:
3551 IncrementalMarking* marking_;
3552 };
3553
3554 // An entry in a DescriptorArray, represented as an (array, index) pair.
3555 class Entry {
3556 public:
Entry(DescriptorArray * descs,int index)3557 inline explicit Entry(DescriptorArray* descs, int index) :
3558 descs_(descs), index_(index) { }
3559
type()3560 inline PropertyType type() { return descs_->GetType(index_); }
GetCallbackObject()3561 inline Object* GetCallbackObject() { return descs_->GetValue(index_); }
3562
3563 private:
3564 DescriptorArray* descs_;
3565 int index_;
3566 };
3567
3568 // Conversion from descriptor number to array indices.
ToKeyIndex(int descriptor_number)3569 static int ToKeyIndex(int descriptor_number) {
3570 return kFirstIndex +
3571 (descriptor_number * kDescriptorSize) +
3572 kDescriptorKey;
3573 }
3574
ToDetailsIndex(int descriptor_number)3575 static int ToDetailsIndex(int descriptor_number) {
3576 return kFirstIndex +
3577 (descriptor_number * kDescriptorSize) +
3578 kDescriptorDetails;
3579 }
3580
ToValueIndex(int descriptor_number)3581 static int ToValueIndex(int descriptor_number) {
3582 return kFirstIndex +
3583 (descriptor_number * kDescriptorSize) +
3584 kDescriptorValue;
3585 }
3586
3587 // Transfer a complete descriptor from the src descriptor array to this
3588 // descriptor array.
3589 void CopyFrom(int index,
3590 DescriptorArray* src,
3591 const WhitenessWitness&);
3592
3593 inline void Set(int descriptor_number,
3594 Descriptor* desc,
3595 const WhitenessWitness&);
3596
3597 inline void Append(Descriptor* desc, const WhitenessWitness&);
3598
3599 // Swap first and second descriptor.
3600 inline void SwapSortedKeys(int first, int second);
3601
3602 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3603 };
3604
3605
3606 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3607
3608 template<SearchMode search_mode, typename T>
3609 inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
3610
3611
3612 template<SearchMode search_mode, typename T>
3613 inline int Search(T* array, Name* name, int valid_entries = 0);
3614
3615
3616 // HashTable is a subclass of FixedArray that implements a hash table
3617 // that uses open addressing and quadratic probing.
3618 //
3619 // In order for the quadratic probing to work, elements that have not
3620 // yet been used and elements that have been deleted are
3621 // distinguished. Probing continues when deleted elements are
3622 // encountered and stops when unused elements are encountered.
3623 //
3624 // - Elements with key == undefined have not been used yet.
3625 // - Elements with key == the_hole have been deleted.
3626 //
3627 // The hash table class is parameterized with a Shape and a Key.
3628 // Shape must be a class with the following interface:
3629 // class ExampleShape {
3630 // public:
3631 // // Tells whether key matches other.
3632 // static bool IsMatch(Key key, Object* other);
3633 // // Returns the hash value for key.
3634 // static uint32_t Hash(Key key);
3635 // // Returns the hash value for object.
3636 // static uint32_t HashForObject(Key key, Object* object);
3637 // // Convert key to an object.
3638 // static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
3639 // // The prefix size indicates number of elements in the beginning
3640 // // of the backing storage.
3641 // static const int kPrefixSize = ..;
3642 // // The Element size indicates number of elements per entry.
3643 // static const int kEntrySize = ..;
3644 // };
3645 // The prefix size indicates an amount of memory in the
3646 // beginning of the backing storage that can be used for non-element
3647 // information by subclasses.
3648
3649 template<typename Key>
3650 class BaseShape {
3651 public:
3652 static const bool UsesSeed = false;
Hash(Key key)3653 static uint32_t Hash(Key key) { return 0; }
SeededHash(Key key,uint32_t seed)3654 static uint32_t SeededHash(Key key, uint32_t seed) {
3655 ASSERT(UsesSeed);
3656 return Hash(key);
3657 }
HashForObject(Key key,Object * object)3658 static uint32_t HashForObject(Key key, Object* object) { return 0; }
SeededHashForObject(Key key,uint32_t seed,Object * object)3659 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
3660 ASSERT(UsesSeed);
3661 return HashForObject(key, object);
3662 }
3663 };
3664
3665 template<typename Derived, typename Shape, typename Key>
3666 class HashTable: public FixedArray {
3667 public:
3668 // Wrapper methods
Hash(Key key)3669 inline uint32_t Hash(Key key) {
3670 if (Shape::UsesSeed) {
3671 return Shape::SeededHash(key, GetHeap()->HashSeed());
3672 } else {
3673 return Shape::Hash(key);
3674 }
3675 }
3676
HashForObject(Key key,Object * object)3677 inline uint32_t HashForObject(Key key, Object* object) {
3678 if (Shape::UsesSeed) {
3679 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
3680 } else {
3681 return Shape::HashForObject(key, object);
3682 }
3683 }
3684
3685 // Returns the number of elements in the hash table.
NumberOfElements()3686 int NumberOfElements() {
3687 return Smi::cast(get(kNumberOfElementsIndex))->value();
3688 }
3689
3690 // Returns the number of deleted elements in the hash table.
NumberOfDeletedElements()3691 int NumberOfDeletedElements() {
3692 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3693 }
3694
3695 // Returns the capacity of the hash table.
Capacity()3696 int Capacity() {
3697 return Smi::cast(get(kCapacityIndex))->value();
3698 }
3699
3700 // ElementAdded should be called whenever an element is added to a
3701 // hash table.
ElementAdded()3702 void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); }
3703
3704 // ElementRemoved should be called whenever an element is removed from
3705 // a hash table.
ElementRemoved()3706 void ElementRemoved() {
3707 SetNumberOfElements(NumberOfElements() - 1);
3708 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
3709 }
ElementsRemoved(int n)3710 void ElementsRemoved(int n) {
3711 SetNumberOfElements(NumberOfElements() - n);
3712 SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
3713 }
3714
3715 // Returns a new HashTable object.
3716 MUST_USE_RESULT static Handle<Derived> New(
3717 Isolate* isolate,
3718 int at_least_space_for,
3719 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
3720 PretenureFlag pretenure = NOT_TENURED);
3721
3722 // Computes the required capacity for a table holding the given
3723 // number of elements. May be more than HashTable::kMaxCapacity.
3724 static int ComputeCapacity(int at_least_space_for);
3725
3726 // Returns the key at entry.
KeyAt(int entry)3727 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
3728
3729 // Tells whether k is a real key. The hole and undefined are not allowed
3730 // as keys and can be used to indicate missing or deleted elements.
IsKey(Object * k)3731 bool IsKey(Object* k) {
3732 return !k->IsTheHole() && !k->IsUndefined();
3733 }
3734
3735 // Garbage collection support.
3736 void IteratePrefix(ObjectVisitor* visitor);
3737 void IterateElements(ObjectVisitor* visitor);
3738
3739 // Casting.
3740 static inline HashTable* cast(Object* obj);
3741
3742 // Compute the probe offset (quadratic probing).
INLINE(static uint32_t GetProbeOffset (uint32_t n))3743 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3744 return (n + n * n) >> 1;
3745 }
3746
3747 static const int kNumberOfElementsIndex = 0;
3748 static const int kNumberOfDeletedElementsIndex = 1;
3749 static const int kCapacityIndex = 2;
3750 static const int kPrefixStartIndex = 3;
3751 static const int kElementsStartIndex =
3752 kPrefixStartIndex + Shape::kPrefixSize;
3753 static const int kEntrySize = Shape::kEntrySize;
3754 static const int kElementsStartOffset =
3755 kHeaderSize + kElementsStartIndex * kPointerSize;
3756 static const int kCapacityOffset =
3757 kHeaderSize + kCapacityIndex * kPointerSize;
3758
3759 // Constant used for denoting a absent entry.
3760 static const int kNotFound = -1;
3761
3762 // Maximal capacity of HashTable. Based on maximal length of underlying
3763 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3764 // cannot overflow.
3765 static const int kMaxCapacity =
3766 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
3767
3768 // Find entry for key otherwise return kNotFound.
3769 inline int FindEntry(Key key);
3770 int FindEntry(Isolate* isolate, Key key);
3771
3772 // Rehashes the table in-place.
3773 void Rehash(Key key);
3774
3775 protected:
3776 friend class ObjectHashTable;
3777
3778 // Find the entry at which to insert element with the given key that
3779 // has the given hash value.
3780 uint32_t FindInsertionEntry(uint32_t hash);
3781
3782 // Returns the index for an entry (of the key)
EntryToIndex(int entry)3783 static inline int EntryToIndex(int entry) {
3784 return (entry * kEntrySize) + kElementsStartIndex;
3785 }
3786
3787 // Update the number of elements in the hash table.
SetNumberOfElements(int nof)3788 void SetNumberOfElements(int nof) {
3789 set(kNumberOfElementsIndex, Smi::FromInt(nof));
3790 }
3791
3792 // Update the number of deleted elements in the hash table.
SetNumberOfDeletedElements(int nod)3793 void SetNumberOfDeletedElements(int nod) {
3794 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
3795 }
3796
3797 // Sets the capacity of the hash table.
SetCapacity(int capacity)3798 void SetCapacity(int capacity) {
3799 // To scale a computed hash code to fit within the hash table, we
3800 // use bit-wise AND with a mask, so the capacity must be positive
3801 // and non-zero.
3802 ASSERT(capacity > 0);
3803 ASSERT(capacity <= kMaxCapacity);
3804 set(kCapacityIndex, Smi::FromInt(capacity));
3805 }
3806
3807
3808 // Returns probe entry.
GetProbe(uint32_t hash,uint32_t number,uint32_t size)3809 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3810 ASSERT(IsPowerOf2(size));
3811 return (hash + GetProbeOffset(number)) & (size - 1);
3812 }
3813
FirstProbe(uint32_t hash,uint32_t size)3814 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3815 return hash & (size - 1);
3816 }
3817
NextProbe(uint32_t last,uint32_t number,uint32_t size)3818 inline static uint32_t NextProbe(
3819 uint32_t last, uint32_t number, uint32_t size) {
3820 return (last + number) & (size - 1);
3821 }
3822
3823 // Attempt to shrink hash table after removal of key.
3824 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
3825
3826 // Ensure enough space for n additional elements.
3827 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3828 Handle<Derived> table,
3829 int n,
3830 Key key,
3831 PretenureFlag pretenure = NOT_TENURED);
3832
3833 private:
3834 // Returns _expected_ if one of entries given by the first _probe_ probes is
3835 // equal to _expected_. Otherwise, returns the entry given by the probe
3836 // number _probe_.
3837 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3838
3839 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3840
3841 // Rehashes this hash-table into the new table.
3842 void Rehash(Handle<Derived> new_table, Key key);
3843 };
3844
3845
3846 // HashTableKey is an abstract superclass for virtual key behavior.
3847 class HashTableKey {
3848 public:
3849 // Returns whether the other object matches this key.
3850 virtual bool IsMatch(Object* other) = 0;
3851 // Returns the hash value for this key.
3852 virtual uint32_t Hash() = 0;
3853 // Returns the hash value for object.
3854 virtual uint32_t HashForObject(Object* key) = 0;
3855 // Returns the key object for storing into the hash table.
3856 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
3857 // Required.
~HashTableKey()3858 virtual ~HashTableKey() {}
3859 };
3860
3861
3862 class StringTableShape : public BaseShape<HashTableKey*> {
3863 public:
IsMatch(HashTableKey * key,Object * value)3864 static inline bool IsMatch(HashTableKey* key, Object* value) {
3865 return key->IsMatch(value);
3866 }
3867
Hash(HashTableKey * key)3868 static inline uint32_t Hash(HashTableKey* key) {
3869 return key->Hash();
3870 }
3871
HashForObject(HashTableKey * key,Object * object)3872 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3873 return key->HashForObject(object);
3874 }
3875
3876 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
3877
3878 static const int kPrefixSize = 0;
3879 static const int kEntrySize = 1;
3880 };
3881
3882 class SeqOneByteString;
3883
3884 // StringTable.
3885 //
3886 // No special elements in the prefix and the element size is 1
3887 // because only the string itself (the key) needs to be stored.
3888 class StringTable: public HashTable<StringTable,
3889 StringTableShape,
3890 HashTableKey*> {
3891 public:
3892 // Find string in the string table. If it is not there yet, it is
3893 // added. The return value is the string found.
3894 static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
3895 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
3896
3897 // Tries to internalize given string and returns string handle on success
3898 // or an empty handle otherwise.
3899 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3900 Isolate* isolate,
3901 Handle<String> string);
3902
3903 // Looks up a string that is equal to the given string and returns
3904 // string handle if it is found, or an empty handle otherwise.
3905 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3906 Isolate* isolate,
3907 Handle<String> str);
3908 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3909 Isolate* isolate,
3910 uint16_t c1,
3911 uint16_t c2);
3912
3913 // Casting.
3914 static inline StringTable* cast(Object* obj);
3915
3916 private:
3917 template <bool seq_ascii> friend class JsonParser;
3918
3919 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
3920 };
3921
3922
3923 class MapCacheShape : public BaseShape<HashTableKey*> {
3924 public:
IsMatch(HashTableKey * key,Object * value)3925 static inline bool IsMatch(HashTableKey* key, Object* value) {
3926 return key->IsMatch(value);
3927 }
3928
Hash(HashTableKey * key)3929 static inline uint32_t Hash(HashTableKey* key) {
3930 return key->Hash();
3931 }
3932
HashForObject(HashTableKey * key,Object * object)3933 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3934 return key->HashForObject(object);
3935 }
3936
3937 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
3938
3939 static const int kPrefixSize = 0;
3940 static const int kEntrySize = 2;
3941 };
3942
3943
3944 // MapCache.
3945 //
3946 // Maps keys that are a fixed array of unique names to a map.
3947 // Used for canonicalize maps for object literals.
3948 class MapCache: public HashTable<MapCache, MapCacheShape, HashTableKey*> {
3949 public:
3950 // Find cached value for a name key, otherwise return null.
3951 Object* Lookup(FixedArray* key);
3952 static Handle<MapCache> Put(
3953 Handle<MapCache> map_cache, Handle<FixedArray> key, Handle<Map> value);
3954 static inline MapCache* cast(Object* obj);
3955
3956 private:
3957 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
3958 };
3959
3960
3961 template <typename Derived, typename Shape, typename Key>
3962 class Dictionary: public HashTable<Derived, Shape, Key> {
3963 protected:
3964 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
3965
3966 public:
cast(Object * obj)3967 static inline Dictionary* cast(Object* obj) {
3968 return reinterpret_cast<Dictionary*>(obj);
3969 }
3970
3971 // Returns the value at entry.
ValueAt(int entry)3972 Object* ValueAt(int entry) {
3973 return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
3974 }
3975
3976 // Set the value for entry.
ValueAtPut(int entry,Object * value)3977 void ValueAtPut(int entry, Object* value) {
3978 this->set(DerivedHashTable::EntryToIndex(entry) + 1, value);
3979 }
3980
3981 // Returns the property details for the property at entry.
DetailsAt(int entry)3982 PropertyDetails DetailsAt(int entry) {
3983 ASSERT(entry >= 0); // Not found is -1, which is not caught by get().
3984 return PropertyDetails(
3985 Smi::cast(this->get(DerivedHashTable::EntryToIndex(entry) + 2)));
3986 }
3987
3988 // Set the details for entry.
DetailsAtPut(int entry,PropertyDetails value)3989 void DetailsAtPut(int entry, PropertyDetails value) {
3990 this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi());
3991 }
3992
3993 // Sorting support
3994 void CopyValuesTo(FixedArray* elements);
3995
3996 // Delete a property from the dictionary.
3997 static Handle<Object> DeleteProperty(
3998 Handle<Derived> dictionary,
3999 int entry,
4000 JSObject::DeleteMode mode);
4001
4002 // Attempt to shrink the dictionary after deletion of key.
Shrink(Handle<Derived> dictionary,Key key)4003 MUST_USE_RESULT static inline Handle<Derived> Shrink(
4004 Handle<Derived> dictionary,
4005 Key key) {
4006 return DerivedHashTable::Shrink(dictionary, key);
4007 }
4008
4009 // Returns the number of elements in the dictionary filtering out properties
4010 // with the specified attributes.
4011 int NumberOfElementsFilterAttributes(PropertyAttributes filter);
4012
4013 // Returns the number of enumerable elements in the dictionary.
4014 int NumberOfEnumElements();
4015
4016 enum SortMode { UNSORTED, SORTED };
4017 // Copies keys to preallocated fixed array.
4018 void CopyKeysTo(FixedArray* storage,
4019 PropertyAttributes filter,
4020 SortMode sort_mode);
4021 // Fill in details for properties into storage.
4022 void CopyKeysTo(FixedArray* storage,
4023 int index,
4024 PropertyAttributes filter,
4025 SortMode sort_mode);
4026
4027 // Accessors for next enumeration index.
SetNextEnumerationIndex(int index)4028 void SetNextEnumerationIndex(int index) {
4029 ASSERT(index != 0);
4030 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
4031 }
4032
NextEnumerationIndex()4033 int NextEnumerationIndex() {
4034 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
4035 }
4036
4037 // Creates a new dictionary.
4038 MUST_USE_RESULT static Handle<Derived> New(
4039 Isolate* isolate,
4040 int at_least_space_for,
4041 PretenureFlag pretenure = NOT_TENURED);
4042
4043 // Ensure enough space for n additional elements.
4044 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
4045
4046 #ifdef OBJECT_PRINT
4047 void Print(FILE* out = stdout);
4048 #endif
4049 // Returns the key (slow).
4050 Object* SlowReverseLookup(Object* value);
4051
4052 // Sets the entry to (key, value) pair.
4053 inline void SetEntry(int entry,
4054 Handle<Object> key,
4055 Handle<Object> value);
4056 inline void SetEntry(int entry,
4057 Handle<Object> key,
4058 Handle<Object> value,
4059 PropertyDetails details);
4060
4061 MUST_USE_RESULT static Handle<Derived> Add(
4062 Handle<Derived> dictionary,
4063 Key key,
4064 Handle<Object> value,
4065 PropertyDetails details);
4066
4067 protected:
4068 // Generic at put operation.
4069 MUST_USE_RESULT static Handle<Derived> AtPut(
4070 Handle<Derived> dictionary,
4071 Key key,
4072 Handle<Object> value);
4073
4074 // Add entry to dictionary.
4075 static void AddEntry(
4076 Handle<Derived> dictionary,
4077 Key key,
4078 Handle<Object> value,
4079 PropertyDetails details,
4080 uint32_t hash);
4081
4082 // Generate new enumeration indices to avoid enumeration index overflow.
4083 static void GenerateNewEnumerationIndices(Handle<Derived> dictionary);
4084 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
4085 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
4086 };
4087
4088
4089 class NameDictionaryShape : public BaseShape<Handle<Name> > {
4090 public:
4091 static inline bool IsMatch(Handle<Name> key, Object* other);
4092 static inline uint32_t Hash(Handle<Name> key);
4093 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
4094 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
4095 static const int kPrefixSize = 2;
4096 static const int kEntrySize = 3;
4097 static const bool kIsEnumerable = true;
4098 };
4099
4100
4101 class NameDictionary: public Dictionary<NameDictionary,
4102 NameDictionaryShape,
4103 Handle<Name> > {
4104 typedef Dictionary<
4105 NameDictionary, NameDictionaryShape, Handle<Name> > DerivedDictionary;
4106
4107 public:
cast(Object * obj)4108 static inline NameDictionary* cast(Object* obj) {
4109 ASSERT(obj->IsDictionary());
4110 return reinterpret_cast<NameDictionary*>(obj);
4111 }
4112
4113 // Copies enumerable keys to preallocated fixed array.
4114 void CopyEnumKeysTo(FixedArray* storage);
4115 inline static void DoGenerateNewEnumerationIndices(
4116 Handle<NameDictionary> dictionary);
4117
4118 // Find entry for key, otherwise return kNotFound. Optimized version of
4119 // HashTable::FindEntry.
4120 int FindEntry(Handle<Name> key);
4121 };
4122
4123
4124 class NumberDictionaryShape : public BaseShape<uint32_t> {
4125 public:
4126 static inline bool IsMatch(uint32_t key, Object* other);
4127 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
4128 static const int kEntrySize = 3;
4129 static const bool kIsEnumerable = false;
4130 };
4131
4132
4133 class SeededNumberDictionaryShape : public NumberDictionaryShape {
4134 public:
4135 static const bool UsesSeed = true;
4136 static const int kPrefixSize = 2;
4137
4138 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
4139 static inline uint32_t SeededHashForObject(uint32_t key,
4140 uint32_t seed,
4141 Object* object);
4142 };
4143
4144
4145 class UnseededNumberDictionaryShape : public NumberDictionaryShape {
4146 public:
4147 static const int kPrefixSize = 0;
4148
4149 static inline uint32_t Hash(uint32_t key);
4150 static inline uint32_t HashForObject(uint32_t key, Object* object);
4151 };
4152
4153
4154 class SeededNumberDictionary
4155 : public Dictionary<SeededNumberDictionary,
4156 SeededNumberDictionaryShape,
4157 uint32_t> {
4158 public:
cast(Object * obj)4159 static SeededNumberDictionary* cast(Object* obj) {
4160 ASSERT(obj->IsDictionary());
4161 return reinterpret_cast<SeededNumberDictionary*>(obj);
4162 }
4163
4164 // Type specific at put (default NONE attributes is used when adding).
4165 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
4166 Handle<SeededNumberDictionary> dictionary,
4167 uint32_t key,
4168 Handle<Object> value);
4169 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
4170 Handle<SeededNumberDictionary> dictionary,
4171 uint32_t key,
4172 Handle<Object> value,
4173 PropertyDetails details);
4174
4175 // Set an existing entry or add a new one if needed.
4176 // Return the updated dictionary.
4177 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
4178 Handle<SeededNumberDictionary> dictionary,
4179 uint32_t key,
4180 Handle<Object> value,
4181 PropertyDetails details);
4182
4183 void UpdateMaxNumberKey(uint32_t key);
4184
4185 // If slow elements are required we will never go back to fast-case
4186 // for the elements kept in this dictionary. We require slow
4187 // elements if an element has been added at an index larger than
4188 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
4189 // when defining a getter or setter with a number key.
4190 inline bool requires_slow_elements();
4191 inline void set_requires_slow_elements();
4192
4193 // Get the value of the max number key that has been added to this
4194 // dictionary. max_number_key can only be called if
4195 // requires_slow_elements returns false.
4196 inline uint32_t max_number_key();
4197
4198 // Bit masks.
4199 static const int kRequiresSlowElementsMask = 1;
4200 static const int kRequiresSlowElementsTagSize = 1;
4201 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
4202 };
4203
4204
4205 class UnseededNumberDictionary
4206 : public Dictionary<UnseededNumberDictionary,
4207 UnseededNumberDictionaryShape,
4208 uint32_t> {
4209 public:
cast(Object * obj)4210 static UnseededNumberDictionary* cast(Object* obj) {
4211 ASSERT(obj->IsDictionary());
4212 return reinterpret_cast<UnseededNumberDictionary*>(obj);
4213 }
4214
4215 // Type specific at put (default NONE attributes is used when adding).
4216 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
4217 Handle<UnseededNumberDictionary> dictionary,
4218 uint32_t key,
4219 Handle<Object> value);
4220 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
4221 Handle<UnseededNumberDictionary> dictionary,
4222 uint32_t key,
4223 Handle<Object> value);
4224
4225 // Set an existing entry or add a new one if needed.
4226 // Return the updated dictionary.
4227 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
4228 Handle<UnseededNumberDictionary> dictionary,
4229 uint32_t key,
4230 Handle<Object> value);
4231 };
4232
4233
4234 class ObjectHashTableShape : public BaseShape<Handle<Object> > {
4235 public:
4236 static inline bool IsMatch(Handle<Object> key, Object* other);
4237 static inline uint32_t Hash(Handle<Object> key);
4238 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4239 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4240 static const int kPrefixSize = 0;
4241 static const int kEntrySize = 2;
4242 };
4243
4244
4245 // ObjectHashTable maps keys that are arbitrary objects to object values by
4246 // using the identity hash of the key for hashing purposes.
4247 class ObjectHashTable: public HashTable<ObjectHashTable,
4248 ObjectHashTableShape,
4249 Handle<Object> > {
4250 typedef HashTable<
4251 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
4252 public:
cast(Object * obj)4253 static inline ObjectHashTable* cast(Object* obj) {
4254 ASSERT(obj->IsHashTable());
4255 return reinterpret_cast<ObjectHashTable*>(obj);
4256 }
4257
4258 // Attempt to shrink hash table after removal of key.
4259 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
4260 Handle<ObjectHashTable> table,
4261 Handle<Object> key);
4262
4263 // Looks up the value associated with the given key. The hole value is
4264 // returned in case the key is not present.
4265 Object* Lookup(Handle<Object> key);
4266
4267 // Adds (or overwrites) the value associated with the given key.
4268 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
4269 Handle<Object> key,
4270 Handle<Object> value);
4271
4272 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
4273 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
4274 Handle<Object> key,
4275 bool* was_present);
4276
4277 private:
4278 friend class MarkCompactCollector;
4279
4280 void AddEntry(int entry, Object* key, Object* value);
4281 void RemoveEntry(int entry);
4282
4283 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)4284 static inline int EntryToValueIndex(int entry) {
4285 return EntryToIndex(entry) + 1;
4286 }
4287 };
4288
4289
4290 // OrderedHashTable is a HashTable with Object keys that preserves
4291 // insertion order. There are Map and Set interfaces (OrderedHashMap
4292 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
4293 //
4294 // Only Object* keys are supported, with Object::SameValueZero() used as the
4295 // equality operator and Object::GetHash() for the hash function.
4296 //
4297 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
4298 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
4299 // Originally attributed to Tyler Close.
4300 //
4301 // Memory layout:
4302 // [0]: bucket count
4303 // [1]: element count
4304 // [2]: deleted element count
4305 // [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
4306 // offset into the data table (see below) where the
4307 // first item in this bucket is stored.
4308 // [3 + NumberOfBuckets()..length]: "data table", an array of length
4309 // Capacity() * kEntrySize, where the first entrysize
4310 // items are handled by the derived class and the
4311 // item at kChainOffset is another entry into the
4312 // data table indicating the next entry in this hash
4313 // bucket.
4314 //
4315 // When we transition the table to a new version we obsolete it and reuse parts
4316 // of the memory to store information how to transition an iterator to the new
4317 // table:
4318 //
4319 // Memory layout for obsolete table:
4320 // [0]: bucket count
4321 // [1]: Next newer table
4322 // [2]: Number of removed holes or -1 when the table was cleared.
4323 // [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
4324 // [3 + NumberOfRemovedHoles()..length]: Not used
4325 //
4326 template<class Derived, class Iterator, int entrysize>
4327 class OrderedHashTable: public FixedArray {
4328 public:
4329 // Returns an OrderedHashTable with a capacity of at least |capacity|.
4330 static Handle<Derived> Allocate(
4331 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
4332
4333 // Returns an OrderedHashTable (possibly |table|) with enough space
4334 // to add at least one new element.
4335 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
4336
4337 // Returns an OrderedHashTable (possibly |table|) that's shrunken
4338 // if possible.
4339 static Handle<Derived> Shrink(Handle<Derived> table);
4340
4341 // Returns a new empty OrderedHashTable and records the clearing so that
4342 // exisiting iterators can be updated.
4343 static Handle<Derived> Clear(Handle<Derived> table);
4344
4345 // Returns an OrderedHashTable (possibly |table|) where |key| has been
4346 // removed.
4347 static Handle<Derived> Remove(Handle<Derived> table, Handle<Object> key,
4348 bool* was_present);
4349
4350 // Returns kNotFound if the key isn't present.
4351 int FindEntry(Handle<Object> key);
4352
NumberOfElements()4353 int NumberOfElements() {
4354 return Smi::cast(get(kNumberOfElementsIndex))->value();
4355 }
4356
NumberOfDeletedElements()4357 int NumberOfDeletedElements() {
4358 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
4359 }
4360
UsedCapacity()4361 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
4362
NumberOfBuckets()4363 int NumberOfBuckets() {
4364 return Smi::cast(get(kNumberOfBucketsIndex))->value();
4365 }
4366
4367 // Returns the index into the data table where the new entry
4368 // should be placed. The table is assumed to have enough space
4369 // for a new entry.
4370 int AddEntry(int hash);
4371
4372 // Removes the entry, and puts the_hole in entrysize pointers
4373 // (leaving the hash table chain intact).
4374 void RemoveEntry(int entry);
4375
4376 // Returns an index into |this| for the given entry.
EntryToIndex(int entry)4377 int EntryToIndex(int entry) {
4378 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
4379 }
4380
KeyAt(int entry)4381 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
4382
IsObsolete()4383 bool IsObsolete() {
4384 return !get(kNextTableIndex)->IsSmi();
4385 }
4386
4387 // The next newer table. This is only valid if the table is obsolete.
NextTable()4388 Derived* NextTable() {
4389 return Derived::cast(get(kNextTableIndex));
4390 }
4391
4392 // When the table is obsolete we store the indexes of the removed holes.
RemovedIndexAt(int index)4393 int RemovedIndexAt(int index) {
4394 return Smi::cast(get(kRemovedHolesIndex + index))->value();
4395 }
4396
4397 static const int kNotFound = -1;
4398 static const int kMinCapacity = 4;
4399
4400 private:
4401 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
4402
SetNumberOfBuckets(int num)4403 void SetNumberOfBuckets(int num) {
4404 set(kNumberOfBucketsIndex, Smi::FromInt(num));
4405 }
4406
SetNumberOfElements(int num)4407 void SetNumberOfElements(int num) {
4408 set(kNumberOfElementsIndex, Smi::FromInt(num));
4409 }
4410
SetNumberOfDeletedElements(int num)4411 void SetNumberOfDeletedElements(int num) {
4412 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
4413 }
4414
Capacity()4415 int Capacity() {
4416 return NumberOfBuckets() * kLoadFactor;
4417 }
4418
4419 // Returns the next entry for the given entry.
ChainAt(int entry)4420 int ChainAt(int entry) {
4421 return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
4422 }
4423
HashToBucket(int hash)4424 int HashToBucket(int hash) {
4425 return hash & (NumberOfBuckets() - 1);
4426 }
4427
HashToEntry(int hash)4428 int HashToEntry(int hash) {
4429 int bucket = HashToBucket(hash);
4430 return Smi::cast(get(kHashTableStartIndex + bucket))->value();
4431 }
4432
SetNextTable(Derived * next_table)4433 void SetNextTable(Derived* next_table) {
4434 set(kNextTableIndex, next_table);
4435 }
4436
SetRemovedIndexAt(int index,int removed_index)4437 void SetRemovedIndexAt(int index, int removed_index) {
4438 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
4439 }
4440
4441 static const int kNumberOfBucketsIndex = 0;
4442 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
4443 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
4444 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
4445
4446 static const int kNextTableIndex = kNumberOfElementsIndex;
4447 static const int kRemovedHolesIndex = kHashTableStartIndex;
4448
4449 static const int kEntrySize = entrysize + 1;
4450 static const int kChainOffset = entrysize;
4451
4452 static const int kLoadFactor = 2;
4453 static const int kMaxCapacity =
4454 (FixedArray::kMaxLength - kHashTableStartIndex)
4455 / (1 + (kEntrySize * kLoadFactor));
4456 };
4457
4458
4459 class JSSetIterator;
4460
4461
4462 class OrderedHashSet: public OrderedHashTable<
4463 OrderedHashSet, JSSetIterator, 1> {
4464 public:
cast(Object * obj)4465 static OrderedHashSet* cast(Object* obj) {
4466 ASSERT(obj->IsOrderedHashTable());
4467 return reinterpret_cast<OrderedHashSet*>(obj);
4468 }
4469
4470 bool Contains(Handle<Object> key);
4471 static Handle<OrderedHashSet> Add(
4472 Handle<OrderedHashSet> table, Handle<Object> key);
4473 };
4474
4475
4476 class JSMapIterator;
4477
4478
4479 class OrderedHashMap:public OrderedHashTable<
4480 OrderedHashMap, JSMapIterator, 2> {
4481 public:
cast(Object * obj)4482 static OrderedHashMap* cast(Object* obj) {
4483 ASSERT(obj->IsOrderedHashTable());
4484 return reinterpret_cast<OrderedHashMap*>(obj);
4485 }
4486
4487 Object* Lookup(Handle<Object> key);
4488 static Handle<OrderedHashMap> Put(
4489 Handle<OrderedHashMap> table,
4490 Handle<Object> key,
4491 Handle<Object> value);
4492
4493 private:
ValueAt(int entry)4494 Object* ValueAt(int entry) {
4495 return get(EntryToIndex(entry) + kValueOffset);
4496 }
4497
4498 static const int kValueOffset = 1;
4499 };
4500
4501
4502 template <int entrysize>
4503 class WeakHashTableShape : public BaseShape<Handle<Object> > {
4504 public:
4505 static inline bool IsMatch(Handle<Object> key, Object* other);
4506 static inline uint32_t Hash(Handle<Object> key);
4507 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4508 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4509 static const int kPrefixSize = 0;
4510 static const int kEntrySize = entrysize;
4511 };
4512
4513
4514 // WeakHashTable maps keys that are arbitrary objects to object values.
4515 // It is used for the global weak hash table that maps objects
4516 // embedded in optimized code to dependent code lists.
4517 class WeakHashTable: public HashTable<WeakHashTable,
4518 WeakHashTableShape<2>,
4519 Handle<Object> > {
4520 typedef HashTable<
4521 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
4522 public:
cast(Object * obj)4523 static inline WeakHashTable* cast(Object* obj) {
4524 ASSERT(obj->IsHashTable());
4525 return reinterpret_cast<WeakHashTable*>(obj);
4526 }
4527
4528 // Looks up the value associated with the given key. The hole value is
4529 // returned in case the key is not present.
4530 Object* Lookup(Handle<Object> key);
4531
4532 // Adds (or overwrites) the value associated with the given key. Mapping a
4533 // key to the hole value causes removal of the whole entry.
4534 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
4535 Handle<Object> key,
4536 Handle<Object> value);
4537
4538 // This function is called when heap verification is turned on.
Zap(Object * value)4539 void Zap(Object* value) {
4540 int capacity = Capacity();
4541 for (int i = 0; i < capacity; i++) {
4542 set(EntryToIndex(i), value);
4543 set(EntryToValueIndex(i), value);
4544 }
4545 }
4546
4547 private:
4548 friend class MarkCompactCollector;
4549
4550 void AddEntry(int entry, Handle<Object> key, Handle<Object> value);
4551
4552 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)4553 static inline int EntryToValueIndex(int entry) {
4554 return EntryToIndex(entry) + 1;
4555 }
4556 };
4557
4558
4559 // JSFunctionResultCache caches results of some JSFunction invocation.
4560 // It is a fixed array with fixed structure:
4561 // [0]: factory function
4562 // [1]: finger index
4563 // [2]: current cache size
4564 // [3]: dummy field.
4565 // The rest of array are key/value pairs.
4566 class JSFunctionResultCache: public FixedArray {
4567 public:
4568 static const int kFactoryIndex = 0;
4569 static const int kFingerIndex = kFactoryIndex + 1;
4570 static const int kCacheSizeIndex = kFingerIndex + 1;
4571 static const int kDummyIndex = kCacheSizeIndex + 1;
4572 static const int kEntriesIndex = kDummyIndex + 1;
4573
4574 static const int kEntrySize = 2; // key + value
4575
4576 static const int kFactoryOffset = kHeaderSize;
4577 static const int kFingerOffset = kFactoryOffset + kPointerSize;
4578 static const int kCacheSizeOffset = kFingerOffset + kPointerSize;
4579
4580 inline void MakeZeroSize();
4581 inline void Clear();
4582
4583 inline int size();
4584 inline void set_size(int size);
4585 inline int finger_index();
4586 inline void set_finger_index(int finger_index);
4587
4588 // Casting
4589 static inline JSFunctionResultCache* cast(Object* obj);
4590
4591 DECLARE_VERIFIER(JSFunctionResultCache)
4592 };
4593
4594
4595 // ScopeInfo represents information about different scopes of a source
4596 // program and the allocation of the scope's variables. Scope information
4597 // is stored in a compressed form in ScopeInfo objects and is used
4598 // at runtime (stack dumps, deoptimization, etc.).
4599
4600 // This object provides quick access to scope info details for runtime
4601 // routines.
4602 class ScopeInfo : public FixedArray {
4603 public:
4604 static inline ScopeInfo* cast(Object* object);
4605
4606 // Return the type of this scope.
4607 ScopeType scope_type();
4608
4609 // Does this scope call eval?
4610 bool CallsEval();
4611
4612 // Return the strict mode of this scope.
4613 StrictMode strict_mode();
4614
4615 // Does this scope make a sloppy eval call?
CallsSloppyEval()4616 bool CallsSloppyEval() { return CallsEval() && strict_mode() == SLOPPY; }
4617
4618 // Return the total number of locals allocated on the stack and in the
4619 // context. This includes the parameters that are allocated in the context.
4620 int LocalCount();
4621
4622 // Return the number of stack slots for code. This number consists of two
4623 // parts:
4624 // 1. One stack slot per stack allocated local.
4625 // 2. One stack slot for the function name if it is stack allocated.
4626 int StackSlotCount();
4627
4628 // Return the number of context slots for code if a context is allocated. This
4629 // number consists of three parts:
4630 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4631 // 2. One context slot per context allocated local.
4632 // 3. One context slot for the function name if it is context allocated.
4633 // Parameters allocated in the context count as context allocated locals. If
4634 // no contexts are allocated for this scope ContextLength returns 0.
4635 int ContextLength();
4636
4637 // Is this scope the scope of a named function expression?
4638 bool HasFunctionName();
4639
4640 // Return if this has context allocated locals.
4641 bool HasHeapAllocatedLocals();
4642
4643 // Return if contexts are allocated for this scope.
4644 bool HasContext();
4645
4646 // Return the function_name if present.
4647 String* FunctionName();
4648
4649 // Return the name of the given parameter.
4650 String* ParameterName(int var);
4651
4652 // Return the name of the given local.
4653 String* LocalName(int var);
4654
4655 // Return the name of the given stack local.
4656 String* StackLocalName(int var);
4657
4658 // Return the name of the given context local.
4659 String* ContextLocalName(int var);
4660
4661 // Return the mode of the given context local.
4662 VariableMode ContextLocalMode(int var);
4663
4664 // Return the initialization flag of the given context local.
4665 InitializationFlag ContextLocalInitFlag(int var);
4666
4667 // Return true if this local was introduced by the compiler, and should not be
4668 // exposed to the user in a debugger.
4669 bool LocalIsSynthetic(int var);
4670
4671 // Lookup support for serialized scope info. Returns the
4672 // the stack slot index for a given slot name if the slot is
4673 // present; otherwise returns a value < 0. The name must be an internalized
4674 // string.
4675 int StackSlotIndex(String* name);
4676
4677 // Lookup support for serialized scope info. Returns the
4678 // context slot index for a given slot name if the slot is present; otherwise
4679 // returns a value < 0. The name must be an internalized string.
4680 // If the slot is present and mode != NULL, sets *mode to the corresponding
4681 // mode for that variable.
4682 static int ContextSlotIndex(Handle<ScopeInfo> scope_info,
4683 Handle<String> name,
4684 VariableMode* mode,
4685 InitializationFlag* init_flag);
4686
4687 // Lookup support for serialized scope info. Returns the
4688 // parameter index for a given parameter name if the parameter is present;
4689 // otherwise returns a value < 0. The name must be an internalized string.
4690 int ParameterIndex(String* name);
4691
4692 // Lookup support for serialized scope info. Returns the function context
4693 // slot index if the function name is present and context-allocated (named
4694 // function expressions, only), otherwise returns a value < 0. The name
4695 // must be an internalized string.
4696 int FunctionContextSlotIndex(String* name, VariableMode* mode);
4697
4698
4699 // Copies all the context locals into an object used to materialize a scope.
4700 static bool CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
4701 Handle<Context> context,
4702 Handle<JSObject> scope_object);
4703
4704
4705 static Handle<ScopeInfo> Create(Scope* scope, Zone* zone);
4706
4707 // Serializes empty scope info.
4708 static ScopeInfo* Empty(Isolate* isolate);
4709
4710 #ifdef DEBUG
4711 void Print();
4712 #endif
4713
4714 // The layout of the static part of a ScopeInfo is as follows. Each entry is
4715 // numeric and occupies one array slot.
4716 // 1. A set of properties of the scope
4717 // 2. The number of parameters. This only applies to function scopes. For
4718 // non-function scopes this is 0.
4719 // 3. The number of non-parameter variables allocated on the stack.
4720 // 4. The number of non-parameter and parameter variables allocated in the
4721 // context.
4722 #define FOR_EACH_NUMERIC_FIELD(V) \
4723 V(Flags) \
4724 V(ParameterCount) \
4725 V(StackLocalCount) \
4726 V(ContextLocalCount)
4727
4728 #define FIELD_ACCESSORS(name) \
4729 void Set##name(int value) { \
4730 set(k##name, Smi::FromInt(value)); \
4731 } \
4732 int name() { \
4733 if (length() > 0) { \
4734 return Smi::cast(get(k##name))->value(); \
4735 } else { \
4736 return 0; \
4737 } \
4738 }
4739 FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS)
4740 #undef FIELD_ACCESSORS
4741
4742 private:
4743 enum {
4744 #define DECL_INDEX(name) k##name,
4745 FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
4746 #undef DECL_INDEX
4747 #undef FOR_EACH_NUMERIC_FIELD
4748 kVariablePartIndex
4749 };
4750
4751 // The layout of the variable part of a ScopeInfo is as follows:
4752 // 1. ParameterEntries:
4753 // This part stores the names of the parameters for function scopes. One
4754 // slot is used per parameter, so in total this part occupies
4755 // ParameterCount() slots in the array. For other scopes than function
4756 // scopes ParameterCount() is 0.
4757 // 2. StackLocalEntries:
4758 // Contains the names of local variables that are allocated on the stack,
4759 // in increasing order of the stack slot index. One slot is used per stack
4760 // local, so in total this part occupies StackLocalCount() slots in the
4761 // array.
4762 // 3. ContextLocalNameEntries:
4763 // Contains the names of local variables and parameters that are allocated
4764 // in the context. They are stored in increasing order of the context slot
4765 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4766 // context local, so in total this part occupies ContextLocalCount() slots
4767 // in the array.
4768 // 4. ContextLocalInfoEntries:
4769 // Contains the variable modes and initialization flags corresponding to
4770 // the context locals in ContextLocalNameEntries. One slot is used per
4771 // context local, so in total this part occupies ContextLocalCount()
4772 // slots in the array.
4773 // 5. FunctionNameEntryIndex:
4774 // If the scope belongs to a named function expression this part contains
4775 // information about the function variable. It always occupies two array
4776 // slots: a. The name of the function variable.
4777 // b. The context or stack slot index for the variable.
4778 int ParameterEntriesIndex();
4779 int StackLocalEntriesIndex();
4780 int ContextLocalNameEntriesIndex();
4781 int ContextLocalInfoEntriesIndex();
4782 int FunctionNameEntryIndex();
4783
4784 // Location of the function variable for named function expressions.
4785 enum FunctionVariableInfo {
4786 NONE, // No function name present.
4787 STACK, // Function
4788 CONTEXT,
4789 UNUSED
4790 };
4791
4792 // Properties of scopes.
4793 class ScopeTypeField: public BitField<ScopeType, 0, 3> {};
4794 class CallsEvalField: public BitField<bool, 3, 1> {};
4795 class StrictModeField: public BitField<StrictMode, 4, 1> {};
4796 class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
4797 class FunctionVariableMode: public BitField<VariableMode, 7, 3> {};
4798
4799 // BitFields representing the encoded information for context locals in the
4800 // ContextLocalInfoEntries part.
4801 class ContextLocalMode: public BitField<VariableMode, 0, 3> {};
4802 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {};
4803 };
4804
4805
4806 // The cache for maps used by normalized (dictionary mode) objects.
4807 // Such maps do not have property descriptors, so a typical program
4808 // needs very limited number of distinct normalized maps.
4809 class NormalizedMapCache: public FixedArray {
4810 public:
4811 static Handle<NormalizedMapCache> New(Isolate* isolate);
4812
4813 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4814 PropertyNormalizationMode mode);
4815 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
4816
4817 void Clear();
4818
4819 // Casting
4820 static inline NormalizedMapCache* cast(Object* obj);
4821 static inline bool IsNormalizedMapCache(Object* obj);
4822
4823 DECLARE_VERIFIER(NormalizedMapCache)
4824 private:
4825 static const int kEntries = 64;
4826
4827 static inline int GetIndex(Handle<Map> map);
4828
4829 // The following declarations hide base class methods.
4830 Object* get(int index);
4831 void set(int index, Object* value);
4832 };
4833
4834
4835 // ByteArray represents fixed sized byte arrays. Used for the relocation info
4836 // that is attached to code objects.
4837 class ByteArray: public FixedArrayBase {
4838 public:
Size()4839 inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
4840
4841 // Setter and getter.
4842 inline byte get(int index);
4843 inline void set(int index, byte value);
4844
4845 // Treat contents as an int array.
4846 inline int get_int(int index);
4847
SizeFor(int length)4848 static int SizeFor(int length) {
4849 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4850 }
4851 // We use byte arrays for free blocks in the heap. Given a desired size in
4852 // bytes that is a multiple of the word size and big enough to hold a byte
4853 // array, this function returns the number of elements a byte array should
4854 // have.
LengthFor(int size_in_bytes)4855 static int LengthFor(int size_in_bytes) {
4856 ASSERT(IsAligned(size_in_bytes, kPointerSize));
4857 ASSERT(size_in_bytes >= kHeaderSize);
4858 return size_in_bytes - kHeaderSize;
4859 }
4860
4861 // Returns data start address.
4862 inline Address GetDataStartAddress();
4863
4864 // Returns a pointer to the ByteArray object for a given data start address.
4865 static inline ByteArray* FromDataStartAddress(Address address);
4866
4867 // Casting.
4868 static inline ByteArray* cast(Object* obj);
4869
4870 // Dispatched behavior.
ByteArraySize()4871 inline int ByteArraySize() {
4872 return SizeFor(this->length());
4873 }
4874 DECLARE_PRINTER(ByteArray)
4875 DECLARE_VERIFIER(ByteArray)
4876
4877 // Layout description.
4878 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4879
4880 // Maximal memory consumption for a single ByteArray.
4881 static const int kMaxSize = 512 * MB;
4882 // Maximal length of a single ByteArray.
4883 static const int kMaxLength = kMaxSize - kHeaderSize;
4884
4885 private:
4886 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4887 };
4888
4889
4890 // FreeSpace represents fixed sized areas of the heap that are not currently in
4891 // use. Used by the heap and GC.
4892 class FreeSpace: public HeapObject {
4893 public:
4894 // [size]: size of the free space including the header.
4895 inline int size();
4896 inline void set_size(int value);
4897
4898 inline int nobarrier_size();
4899 inline void nobarrier_set_size(int value);
4900
Size()4901 inline int Size() { return size(); }
4902
4903 // Casting.
4904 static inline FreeSpace* cast(Object* obj);
4905
4906 // Dispatched behavior.
4907 DECLARE_PRINTER(FreeSpace)
4908 DECLARE_VERIFIER(FreeSpace)
4909
4910 // Layout description.
4911 // Size is smi tagged when it is stored.
4912 static const int kSizeOffset = HeapObject::kHeaderSize;
4913 static const int kHeaderSize = kSizeOffset + kPointerSize;
4914
4915 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4916
4917 private:
4918 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4919 };
4920
4921
4922 // V has parameters (Type, type, TYPE, C type, element_size)
4923 #define TYPED_ARRAYS(V) \
4924 V(Uint8, uint8, UINT8, uint8_t, 1) \
4925 V(Int8, int8, INT8, int8_t, 1) \
4926 V(Uint16, uint16, UINT16, uint16_t, 2) \
4927 V(Int16, int16, INT16, int16_t, 2) \
4928 V(Uint32, uint32, UINT32, uint32_t, 4) \
4929 V(Int32, int32, INT32, int32_t, 4) \
4930 V(Float32, float32, FLOAT32, float, 4) \
4931 V(Float64, float64, FLOAT64, double, 8) \
4932 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4933
4934
4935
4936 // An ExternalArray represents a fixed-size array of primitive values
4937 // which live outside the JavaScript heap. Its subclasses are used to
4938 // implement the CanvasArray types being defined in the WebGL
4939 // specification. As of this writing the first public draft is not yet
4940 // available, but Khronos members can access the draft at:
4941 // https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html
4942 //
4943 // The semantics of these arrays differ from CanvasPixelArray.
4944 // Out-of-range values passed to the setter are converted via a C
4945 // cast, not clamping. Out-of-range indices cause exceptions to be
4946 // raised rather than being silently ignored.
4947 class ExternalArray: public FixedArrayBase {
4948 public:
is_the_hole(int index)4949 inline bool is_the_hole(int index) { return false; }
4950
4951 // [external_pointer]: The pointer to the external memory area backing this
4952 // external array.
4953 DECL_ACCESSORS(external_pointer, void) // Pointer to the data store.
4954
4955 // Casting.
4956 static inline ExternalArray* cast(Object* obj);
4957
4958 // Maximal acceptable length for an external array.
4959 static const int kMaxLength = 0x3fffffff;
4960
4961 // ExternalArray headers are not quadword aligned.
4962 static const int kExternalPointerOffset =
4963 POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize);
4964 static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
4965 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4966
4967 private:
4968 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray);
4969 };
4970
4971
4972 // A ExternalUint8ClampedArray represents a fixed-size byte array with special
4973 // semantics used for implementing the CanvasPixelArray object. Please see the
4974 // specification at:
4975
4976 // http://www.whatwg.org/specs/web-apps/current-work/
4977 // multipage/the-canvas-element.html#canvaspixelarray
4978 // In particular, write access clamps the value written to 0 or 255 if the
4979 // value written is outside this range.
4980 class ExternalUint8ClampedArray: public ExternalArray {
4981 public:
4982 inline uint8_t* external_uint8_clamped_pointer();
4983
4984 // Setter and getter.
4985 inline uint8_t get_scalar(int index);
4986 static inline Handle<Object> get(Handle<ExternalUint8ClampedArray> array,
4987 int index);
4988 inline void set(int index, uint8_t value);
4989
4990 // This accessor applies the correct conversion from Smi, HeapNumber
4991 // and undefined and clamps the converted value between 0 and 255.
4992 static Handle<Object> SetValue(Handle<ExternalUint8ClampedArray> array,
4993 uint32_t index,
4994 Handle<Object> value);
4995
4996 // Casting.
4997 static inline ExternalUint8ClampedArray* cast(Object* obj);
4998
4999 // Dispatched behavior.
5000 DECLARE_PRINTER(ExternalUint8ClampedArray)
5001 DECLARE_VERIFIER(ExternalUint8ClampedArray)
5002
5003 private:
5004 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8ClampedArray);
5005 };
5006
5007
5008 class ExternalInt8Array: public ExternalArray {
5009 public:
5010 // Setter and getter.
5011 inline int8_t get_scalar(int index);
5012 static inline Handle<Object> get(Handle<ExternalInt8Array> array, int index);
5013 inline void set(int index, int8_t value);
5014
5015 // This accessor applies the correct conversion from Smi, HeapNumber
5016 // and undefined.
5017 static Handle<Object> SetValue(Handle<ExternalInt8Array> array,
5018 uint32_t index,
5019 Handle<Object> value);
5020
5021 // Casting.
5022 static inline ExternalInt8Array* cast(Object* obj);
5023
5024 // Dispatched behavior.
5025 DECLARE_PRINTER(ExternalInt8Array)
5026 DECLARE_VERIFIER(ExternalInt8Array)
5027
5028 private:
5029 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt8Array);
5030 };
5031
5032
5033 class ExternalUint8Array: public ExternalArray {
5034 public:
5035 // Setter and getter.
5036 inline uint8_t get_scalar(int index);
5037 static inline Handle<Object> get(Handle<ExternalUint8Array> array, int index);
5038 inline void set(int index, uint8_t value);
5039
5040 // This accessor applies the correct conversion from Smi, HeapNumber
5041 // and undefined.
5042 static Handle<Object> SetValue(Handle<ExternalUint8Array> array,
5043 uint32_t index,
5044 Handle<Object> value);
5045
5046 // Casting.
5047 static inline ExternalUint8Array* cast(Object* obj);
5048
5049 // Dispatched behavior.
5050 DECLARE_PRINTER(ExternalUint8Array)
5051 DECLARE_VERIFIER(ExternalUint8Array)
5052
5053 private:
5054 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8Array);
5055 };
5056
5057
5058 class ExternalInt16Array: public ExternalArray {
5059 public:
5060 // Setter and getter.
5061 inline int16_t get_scalar(int index);
5062 static inline Handle<Object> get(Handle<ExternalInt16Array> array, int index);
5063 inline void set(int index, int16_t value);
5064
5065 // This accessor applies the correct conversion from Smi, HeapNumber
5066 // and undefined.
5067 static Handle<Object> SetValue(Handle<ExternalInt16Array> array,
5068 uint32_t index,
5069 Handle<Object> value);
5070
5071 // Casting.
5072 static inline ExternalInt16Array* cast(Object* obj);
5073
5074 // Dispatched behavior.
5075 DECLARE_PRINTER(ExternalInt16Array)
5076 DECLARE_VERIFIER(ExternalInt16Array)
5077
5078 private:
5079 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt16Array);
5080 };
5081
5082
5083 class ExternalUint16Array: public ExternalArray {
5084 public:
5085 // Setter and getter.
5086 inline uint16_t get_scalar(int index);
5087 static inline Handle<Object> get(Handle<ExternalUint16Array> array,
5088 int index);
5089 inline void set(int index, uint16_t value);
5090
5091 // This accessor applies the correct conversion from Smi, HeapNumber
5092 // and undefined.
5093 static Handle<Object> SetValue(Handle<ExternalUint16Array> array,
5094 uint32_t index,
5095 Handle<Object> value);
5096
5097 // Casting.
5098 static inline ExternalUint16Array* cast(Object* obj);
5099
5100 // Dispatched behavior.
5101 DECLARE_PRINTER(ExternalUint16Array)
5102 DECLARE_VERIFIER(ExternalUint16Array)
5103
5104 private:
5105 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint16Array);
5106 };
5107
5108
5109 class ExternalInt32Array: public ExternalArray {
5110 public:
5111 // Setter and getter.
5112 inline int32_t get_scalar(int index);
5113 static inline Handle<Object> get(Handle<ExternalInt32Array> array, int index);
5114 inline void set(int index, int32_t value);
5115
5116 // This accessor applies the correct conversion from Smi, HeapNumber
5117 // and undefined.
5118 static Handle<Object> SetValue(Handle<ExternalInt32Array> array,
5119 uint32_t index,
5120 Handle<Object> value);
5121
5122 // Casting.
5123 static inline ExternalInt32Array* cast(Object* obj);
5124
5125 // Dispatched behavior.
5126 DECLARE_PRINTER(ExternalInt32Array)
5127 DECLARE_VERIFIER(ExternalInt32Array)
5128
5129 private:
5130 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt32Array);
5131 };
5132
5133
5134 class ExternalUint32Array: public ExternalArray {
5135 public:
5136 // Setter and getter.
5137 inline uint32_t get_scalar(int index);
5138 static inline Handle<Object> get(Handle<ExternalUint32Array> array,
5139 int index);
5140 inline void set(int index, uint32_t value);
5141
5142 // This accessor applies the correct conversion from Smi, HeapNumber
5143 // and undefined.
5144 static Handle<Object> SetValue(Handle<ExternalUint32Array> array,
5145 uint32_t index,
5146 Handle<Object> value);
5147
5148 // Casting.
5149 static inline ExternalUint32Array* cast(Object* obj);
5150
5151 // Dispatched behavior.
5152 DECLARE_PRINTER(ExternalUint32Array)
5153 DECLARE_VERIFIER(ExternalUint32Array)
5154
5155 private:
5156 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint32Array);
5157 };
5158
5159
5160 class ExternalFloat32Array: public ExternalArray {
5161 public:
5162 // Setter and getter.
5163 inline float get_scalar(int index);
5164 static inline Handle<Object> get(Handle<ExternalFloat32Array> array,
5165 int index);
5166 inline void set(int index, float value);
5167
5168 // This accessor applies the correct conversion from Smi, HeapNumber
5169 // and undefined.
5170 static Handle<Object> SetValue(Handle<ExternalFloat32Array> array,
5171 uint32_t index,
5172 Handle<Object> value);
5173
5174 // Casting.
5175 static inline ExternalFloat32Array* cast(Object* obj);
5176
5177 // Dispatched behavior.
5178 DECLARE_PRINTER(ExternalFloat32Array)
5179 DECLARE_VERIFIER(ExternalFloat32Array)
5180
5181 private:
5182 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat32Array);
5183 };
5184
5185
5186 class ExternalFloat64Array: public ExternalArray {
5187 public:
5188 // Setter and getter.
5189 inline double get_scalar(int index);
5190 static inline Handle<Object> get(Handle<ExternalFloat64Array> array,
5191 int index);
5192 inline void set(int index, double value);
5193
5194 // This accessor applies the correct conversion from Smi, HeapNumber
5195 // and undefined.
5196 static Handle<Object> SetValue(Handle<ExternalFloat64Array> array,
5197 uint32_t index,
5198 Handle<Object> value);
5199
5200 // Casting.
5201 static inline ExternalFloat64Array* cast(Object* obj);
5202
5203 // Dispatched behavior.
5204 DECLARE_PRINTER(ExternalFloat64Array)
5205 DECLARE_VERIFIER(ExternalFloat64Array)
5206
5207 private:
5208 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat64Array);
5209 };
5210
5211
5212 class FixedTypedArrayBase: public FixedArrayBase {
5213 public:
5214 // Casting:
5215 static inline FixedTypedArrayBase* cast(Object* obj);
5216
5217 static const int kDataOffset = kHeaderSize;
5218
5219 inline int size();
5220
5221 inline int TypedArraySize(InstanceType type);
5222
5223 // Use with care: returns raw pointer into heap.
5224 inline void* DataPtr();
5225
5226 inline int DataSize();
5227
5228 private:
5229 inline int DataSize(InstanceType type);
5230
5231 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
5232 };
5233
5234
5235 template <class Traits>
5236 class FixedTypedArray: public FixedTypedArrayBase {
5237 public:
5238 typedef typename Traits::ElementType ElementType;
5239 static const InstanceType kInstanceType = Traits::kInstanceType;
5240
5241 // Casting:
5242 static inline FixedTypedArray<Traits>* cast(Object* obj);
5243
ElementOffset(int index)5244 static inline int ElementOffset(int index) {
5245 return kDataOffset + index * sizeof(ElementType);
5246 }
5247
SizeFor(int length)5248 static inline int SizeFor(int length) {
5249 return ElementOffset(length);
5250 }
5251
5252 inline ElementType get_scalar(int index);
5253 static inline Handle<Object> get(Handle<FixedTypedArray> array, int index);
5254 inline void set(int index, ElementType value);
5255
5256 static inline ElementType from_int(int value);
5257 static inline ElementType from_double(double value);
5258
5259 // This accessor applies the correct conversion from Smi, HeapNumber
5260 // and undefined.
5261 static Handle<Object> SetValue(Handle<FixedTypedArray<Traits> > array,
5262 uint32_t index,
5263 Handle<Object> value);
5264
5265 DECLARE_PRINTER(FixedTypedArray)
5266 DECLARE_VERIFIER(FixedTypedArray)
5267
5268 private:
5269 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
5270 };
5271
5272 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
5273 class Type##ArrayTraits { \
5274 public: /* NOLINT */ \
5275 typedef elementType ElementType; \
5276 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
5277 static const char* Designator() { return #type " array"; } \
5278 static inline Handle<Object> ToHandle(Isolate* isolate, \
5279 elementType scalar); \
5280 static inline elementType defaultValue(); \
5281 }; \
5282 \
5283 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
5284
TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)5285 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
5286
5287 #undef FIXED_TYPED_ARRAY_TRAITS
5288
5289 // DeoptimizationInputData is a fixed array used to hold the deoptimization
5290 // data for code generated by the Hydrogen/Lithium compiler. It also
5291 // contains information about functions that were inlined. If N different
5292 // functions were inlined then first N elements of the literal array will
5293 // contain these functions.
5294 //
5295 // It can be empty.
5296 class DeoptimizationInputData: public FixedArray {
5297 public:
5298 // Layout description. Indices in the array.
5299 static const int kTranslationByteArrayIndex = 0;
5300 static const int kInlinedFunctionCountIndex = 1;
5301 static const int kLiteralArrayIndex = 2;
5302 static const int kOsrAstIdIndex = 3;
5303 static const int kOsrPcOffsetIndex = 4;
5304 static const int kOptimizationIdIndex = 5;
5305 static const int kSharedFunctionInfoIndex = 6;
5306 static const int kFirstDeoptEntryIndex = 7;
5307
5308 // Offsets of deopt entry elements relative to the start of the entry.
5309 static const int kAstIdRawOffset = 0;
5310 static const int kTranslationIndexOffset = 1;
5311 static const int kArgumentsStackHeightOffset = 2;
5312 static const int kPcOffset = 3;
5313 static const int kDeoptEntrySize = 4;
5314
5315 // Simple element accessors.
5316 #define DEFINE_ELEMENT_ACCESSORS(name, type) \
5317 type* name() { \
5318 return type::cast(get(k##name##Index)); \
5319 } \
5320 void Set##name(type* value) { \
5321 set(k##name##Index, value); \
5322 }
5323
5324 DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
5325 DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
5326 DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
5327 DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
5328 DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
5329 DEFINE_ELEMENT_ACCESSORS(OptimizationId, Smi)
5330 DEFINE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
5331
5332 #undef DEFINE_ELEMENT_ACCESSORS
5333
5334 // Accessors for elements of the ith deoptimization entry.
5335 #define DEFINE_ENTRY_ACCESSORS(name, type) \
5336 type* name(int i) { \
5337 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
5338 } \
5339 void Set##name(int i, type* value) { \
5340 set(IndexForEntry(i) + k##name##Offset, value); \
5341 }
5342
5343 DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
5344 DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
5345 DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
5346 DEFINE_ENTRY_ACCESSORS(Pc, Smi)
5347
5348 #undef DEFINE_ENTRY_ACCESSORS
5349
5350 BailoutId AstId(int i) {
5351 return BailoutId(AstIdRaw(i)->value());
5352 }
5353
5354 void SetAstId(int i, BailoutId value) {
5355 SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
5356 }
5357
5358 int DeoptCount() {
5359 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
5360 }
5361
5362 // Allocates a DeoptimizationInputData.
5363 static Handle<DeoptimizationInputData> New(Isolate* isolate,
5364 int deopt_entry_count,
5365 PretenureFlag pretenure);
5366
5367 // Casting.
5368 static inline DeoptimizationInputData* cast(Object* obj);
5369
5370 #ifdef ENABLE_DISASSEMBLER
5371 void DeoptimizationInputDataPrint(FILE* out);
5372 #endif
5373
5374 private:
5375 static int IndexForEntry(int i) {
5376 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
5377 }
5378
5379 static int LengthFor(int entry_count) {
5380 return IndexForEntry(entry_count);
5381 }
5382 };
5383
5384
5385 // DeoptimizationOutputData is a fixed array used to hold the deoptimization
5386 // data for code generated by the full compiler.
5387 // The format of the these objects is
5388 // [i * 2]: Ast ID for ith deoptimization.
5389 // [i * 2 + 1]: PC and state of ith deoptimization
5390 class DeoptimizationOutputData: public FixedArray {
5391 public:
DeoptPoints()5392 int DeoptPoints() { return length() / 2; }
5393
AstId(int index)5394 BailoutId AstId(int index) {
5395 return BailoutId(Smi::cast(get(index * 2))->value());
5396 }
5397
SetAstId(int index,BailoutId id)5398 void SetAstId(int index, BailoutId id) {
5399 set(index * 2, Smi::FromInt(id.ToInt()));
5400 }
5401
PcAndState(int index)5402 Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
SetPcAndState(int index,Smi * offset)5403 void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
5404
LengthOfFixedArray(int deopt_points)5405 static int LengthOfFixedArray(int deopt_points) {
5406 return deopt_points * 2;
5407 }
5408
5409 // Allocates a DeoptimizationOutputData.
5410 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
5411 int number_of_deopt_points,
5412 PretenureFlag pretenure);
5413
5414 // Casting.
5415 static inline DeoptimizationOutputData* cast(Object* obj);
5416
5417 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
5418 void DeoptimizationOutputDataPrint(FILE* out);
5419 #endif
5420 };
5421
5422
5423 // Forward declaration.
5424 class Cell;
5425 class PropertyCell;
5426 class SafepointEntry;
5427 class TypeFeedbackInfo;
5428
5429 // Code describes objects with on-the-fly generated machine code.
5430 class Code: public HeapObject {
5431 public:
5432 // Opaque data type for encapsulating code flags like kind, inline
5433 // cache state, and arguments count.
5434 typedef uint32_t Flags;
5435
5436 #define NON_IC_KIND_LIST(V) \
5437 V(FUNCTION) \
5438 V(OPTIMIZED_FUNCTION) \
5439 V(STUB) \
5440 V(HANDLER) \
5441 V(BUILTIN) \
5442 V(REGEXP)
5443
5444 #define IC_KIND_LIST(V) \
5445 V(LOAD_IC) \
5446 V(KEYED_LOAD_IC) \
5447 V(CALL_IC) \
5448 V(STORE_IC) \
5449 V(KEYED_STORE_IC) \
5450 V(BINARY_OP_IC) \
5451 V(COMPARE_IC) \
5452 V(COMPARE_NIL_IC) \
5453 V(TO_BOOLEAN_IC)
5454
5455 #define CODE_KIND_LIST(V) \
5456 NON_IC_KIND_LIST(V) \
5457 IC_KIND_LIST(V)
5458
5459 enum Kind {
5460 #define DEFINE_CODE_KIND_ENUM(name) name,
5461 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
5462 #undef DEFINE_CODE_KIND_ENUM
5463 NUMBER_OF_KINDS
5464 };
5465
5466 // No more than 16 kinds. The value is currently encoded in four bits in
5467 // Flags.
5468 STATIC_ASSERT(NUMBER_OF_KINDS <= 16);
5469
5470 static const char* Kind2String(Kind kind);
5471
5472 // Types of stubs.
5473 enum StubType {
5474 NORMAL,
5475 FAST
5476 };
5477
5478 static const int kPrologueOffsetNotSet = -1;
5479
5480 #ifdef ENABLE_DISASSEMBLER
5481 // Printing
5482 static const char* ICState2String(InlineCacheState state);
5483 static const char* StubType2String(StubType type);
5484 static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
5485 void Disassemble(const char* name, FILE* out = stdout);
5486 #endif // ENABLE_DISASSEMBLER
5487
5488 // [instruction_size]: Size of the native instructions
5489 inline int instruction_size();
5490 inline void set_instruction_size(int value);
5491
5492 // [relocation_info]: Code relocation information
5493 DECL_ACCESSORS(relocation_info, ByteArray)
5494 void InvalidateRelocation();
5495 void InvalidateEmbeddedObjects();
5496
5497 // [handler_table]: Fixed array containing offsets of exception handlers.
5498 DECL_ACCESSORS(handler_table, FixedArray)
5499
5500 // [deoptimization_data]: Array containing data for deopt.
5501 DECL_ACCESSORS(deoptimization_data, FixedArray)
5502
5503 // [raw_type_feedback_info]: This field stores various things, depending on
5504 // the kind of the code object.
5505 // FUNCTION => type feedback information.
5506 // STUB => various things, e.g. a SMI
5507 DECL_ACCESSORS(raw_type_feedback_info, Object)
5508 inline Object* type_feedback_info();
5509 inline void set_type_feedback_info(
5510 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5511 inline int stub_info();
5512 inline void set_stub_info(int info);
5513
5514 // [next_code_link]: Link for lists of optimized or deoptimized code.
5515 // Note that storage for this field is overlapped with typefeedback_info.
5516 DECL_ACCESSORS(next_code_link, Object)
5517
5518 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
5519 // field does not have to be traced during garbage collection since
5520 // it is only used by the garbage collector itself.
5521 DECL_ACCESSORS(gc_metadata, Object)
5522
5523 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
5524 // at the moment when this object was created.
5525 inline void set_ic_age(int count);
5526 inline int ic_age();
5527
5528 // [prologue_offset]: Offset of the function prologue, used for aging
5529 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
5530 inline int prologue_offset();
5531 inline void set_prologue_offset(int offset);
5532
5533 // Unchecked accessors to be used during GC.
5534 inline ByteArray* unchecked_relocation_info();
5535
5536 inline int relocation_size();
5537
5538 // [flags]: Various code flags.
5539 inline Flags flags();
5540 inline void set_flags(Flags flags);
5541
5542 // [flags]: Access to specific code flags.
5543 inline Kind kind();
5544 inline InlineCacheState ic_state(); // Only valid for IC stubs.
5545 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
5546
5547 inline StubType type(); // Only valid for monomorphic IC stubs.
5548
5549 // Testers for IC stub kinds.
5550 inline bool is_inline_cache_stub();
5551 inline bool is_debug_stub();
is_handler()5552 inline bool is_handler() { return kind() == HANDLER; }
is_load_stub()5553 inline bool is_load_stub() { return kind() == LOAD_IC; }
is_keyed_load_stub()5554 inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
is_store_stub()5555 inline bool is_store_stub() { return kind() == STORE_IC; }
is_keyed_store_stub()5556 inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
is_call_stub()5557 inline bool is_call_stub() { return kind() == CALL_IC; }
is_binary_op_stub()5558 inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
is_compare_ic_stub()5559 inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
is_compare_nil_ic_stub()5560 inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
is_to_boolean_ic_stub()5561 inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
5562 inline bool is_keyed_stub();
is_optimized_code()5563 inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
5564 inline bool is_weak_stub();
5565 inline void mark_as_weak_stub();
5566 inline bool is_invalidated_weak_stub();
5567 inline void mark_as_invalidated_weak_stub();
5568
CanBeWeakStub()5569 inline bool CanBeWeakStub() {
5570 Kind k = kind();
5571 return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
5572 k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
5573 ic_state() == MONOMORPHIC;
5574 }
5575
5576 inline void set_raw_kind_specific_flags1(int value);
5577 inline void set_raw_kind_specific_flags2(int value);
5578
5579 // [major_key]: For kind STUB or BINARY_OP_IC, the major key.
5580 inline int major_key();
5581 inline void set_major_key(int value);
5582 inline bool has_major_key();
5583
5584 // For kind STUB or ICs, tells whether or not a code object was generated by
5585 // the optimizing compiler (but it may not be an optimized function).
5586 bool is_crankshafted();
5587 inline void set_is_crankshafted(bool value);
5588
5589 // [optimizable]: For FUNCTION kind, tells if it is optimizable.
5590 inline bool optimizable();
5591 inline void set_optimizable(bool value);
5592
5593 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5594 // deoptimization support.
5595 inline bool has_deoptimization_support();
5596 inline void set_has_deoptimization_support(bool value);
5597
5598 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5599 // been compiled with debug break slots.
5600 inline bool has_debug_break_slots();
5601 inline void set_has_debug_break_slots(bool value);
5602
5603 // [compiled_with_optimizing]: For FUNCTION kind, tells if it has
5604 // been compiled with IsOptimizing set to true.
5605 inline bool is_compiled_optimizable();
5606 inline void set_compiled_optimizable(bool value);
5607
5608 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5609 // how long the function has been marked for OSR and therefore which
5610 // level of loop nesting we are willing to do on-stack replacement
5611 // for.
5612 inline void set_allow_osr_at_loop_nesting_level(int level);
5613 inline int allow_osr_at_loop_nesting_level();
5614
5615 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5616 // the code object was seen on the stack with no IC patching going on.
5617 inline int profiler_ticks();
5618 inline void set_profiler_ticks(int ticks);
5619
5620 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5621 // reserved in the code prologue.
5622 inline unsigned stack_slots();
5623 inline void set_stack_slots(unsigned slots);
5624
5625 // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in
5626 // the instruction stream where the safepoint table starts.
5627 inline unsigned safepoint_table_offset();
5628 inline void set_safepoint_table_offset(unsigned offset);
5629
5630 // [back_edge_table_start]: For kind FUNCTION, the offset in the
5631 // instruction stream where the back edge table starts.
5632 inline unsigned back_edge_table_offset();
5633 inline void set_back_edge_table_offset(unsigned offset);
5634
5635 inline bool back_edges_patched_for_osr();
5636 inline void set_back_edges_patched_for_osr(bool value);
5637
5638 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
5639 inline byte to_boolean_state();
5640
5641 // [has_function_cache]: For kind STUB tells whether there is a function
5642 // cache is passed to the stub.
5643 inline bool has_function_cache();
5644 inline void set_has_function_cache(bool flag);
5645
5646
5647 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5648 // the code is going to be deoptimized because of dead embedded maps.
5649 inline bool marked_for_deoptimization();
5650 inline void set_marked_for_deoptimization(bool flag);
5651
5652 // [constant_pool]: The constant pool for this function.
5653 inline ConstantPoolArray* constant_pool();
5654 inline void set_constant_pool(Object* constant_pool);
5655
5656 // Get the safepoint entry for the given pc.
5657 SafepointEntry GetSafepointEntry(Address pc);
5658
5659 // Find an object in a stub with a specified map
5660 Object* FindNthObject(int n, Map* match_map);
5661
5662 // Find the first allocation site in an IC stub.
5663 AllocationSite* FindFirstAllocationSite();
5664
5665 // Find the first map in an IC stub.
5666 Map* FindFirstMap();
5667 void FindAllMaps(MapHandleList* maps);
5668
5669 // Find the first handler in an IC stub.
5670 Code* FindFirstHandler();
5671
5672 // Find |length| handlers and put them into |code_list|. Returns false if not
5673 // enough handlers can be found.
5674 bool FindHandlers(CodeHandleList* code_list, int length = -1);
5675
5676 // Find the first name in an IC stub.
5677 Name* FindFirstName();
5678
5679 class FindAndReplacePattern;
5680 // For each (map-to-find, object-to-replace) pair in the pattern, this
5681 // function replaces the corresponding placeholder in the code with the
5682 // object-to-replace. The function assumes that pairs in the pattern come in
5683 // the same order as the placeholders in the code.
5684 void FindAndReplace(const FindAndReplacePattern& pattern);
5685
5686 // The entire code object including its header is copied verbatim to the
5687 // snapshot so that it can be written in one, fast, memcpy during
5688 // deserialization. The deserializer will overwrite some pointers, rather
5689 // like a runtime linker, but the random allocation addresses used in the
5690 // mksnapshot process would still be present in the unlinked snapshot data,
5691 // which would make snapshot production non-reproducible. This method wipes
5692 // out the to-be-overwritten header data for reproducible snapshots.
5693 inline void WipeOutHeader();
5694
5695 // Flags operations.
5696 static inline Flags ComputeFlags(
5697 Kind kind,
5698 InlineCacheState ic_state = UNINITIALIZED,
5699 ExtraICState extra_ic_state = kNoExtraICState,
5700 StubType type = NORMAL,
5701 InlineCacheHolderFlag holder = OWN_MAP);
5702
5703 static inline Flags ComputeMonomorphicFlags(
5704 Kind kind,
5705 ExtraICState extra_ic_state = kNoExtraICState,
5706 InlineCacheHolderFlag holder = OWN_MAP,
5707 StubType type = NORMAL);
5708
5709 static inline Flags ComputeHandlerFlags(
5710 Kind handler_kind,
5711 StubType type = NORMAL,
5712 InlineCacheHolderFlag holder = OWN_MAP);
5713
5714 static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
5715 static inline StubType ExtractTypeFromFlags(Flags flags);
5716 static inline Kind ExtractKindFromFlags(Flags flags);
5717 static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
5718 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
5719
5720 static inline Flags RemoveTypeFromFlags(Flags flags);
5721
5722 // Convert a target address into a code object.
5723 static inline Code* GetCodeFromTargetAddress(Address address);
5724
5725 // Convert an entry address into an object.
5726 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5727
5728 // Returns the address of the first instruction.
5729 inline byte* instruction_start();
5730
5731 // Returns the address right after the last instruction.
5732 inline byte* instruction_end();
5733
5734 // Returns the size of the instructions, padding, and relocation information.
5735 inline int body_size();
5736
5737 // Returns the address of the first relocation info (read backwards!).
5738 inline byte* relocation_start();
5739
5740 // Code entry point.
5741 inline byte* entry();
5742
5743 // Returns true if pc is inside this object's instructions.
5744 inline bool contains(byte* pc);
5745
5746 // Relocate the code by delta bytes. Called to signal that this code
5747 // object has been moved by delta bytes.
5748 void Relocate(intptr_t delta);
5749
5750 // Migrate code described by desc.
5751 void CopyFrom(const CodeDesc& desc);
5752
5753 // Returns the object size for a given body (used for allocation).
SizeFor(int body_size)5754 static int SizeFor(int body_size) {
5755 ASSERT_SIZE_TAG_ALIGNED(body_size);
5756 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
5757 }
5758
5759 // Calculate the size of the code object to report for log events. This takes
5760 // the layout of the code object into account.
ExecutableSize()5761 int ExecutableSize() {
5762 // Check that the assumptions about the layout of the code object holds.
5763 ASSERT_EQ(static_cast<int>(instruction_start() - address()),
5764 Code::kHeaderSize);
5765 return instruction_size() + Code::kHeaderSize;
5766 }
5767
5768 // Locating source position.
5769 int SourcePosition(Address pc);
5770 int SourceStatementPosition(Address pc);
5771
5772 // Casting.
5773 static inline Code* cast(Object* obj);
5774
5775 // Dispatched behavior.
CodeSize()5776 int CodeSize() { return SizeFor(body_size()); }
5777 inline void CodeIterateBody(ObjectVisitor* v);
5778
5779 template<typename StaticVisitor>
5780 inline void CodeIterateBody(Heap* heap);
5781
5782 DECLARE_PRINTER(Code)
5783 DECLARE_VERIFIER(Code)
5784
5785 void ClearInlineCaches();
5786 void ClearInlineCaches(Kind kind);
5787
5788 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5789 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5790
5791 #define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5792 enum Age {
5793 kNotExecutedCodeAge = -2,
5794 kExecutedOnceCodeAge = -1,
5795 kNoAgeCodeAge = 0,
5796 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5797 kAfterLastCodeAge,
5798 kFirstCodeAge = kNotExecutedCodeAge,
5799 kLastCodeAge = kAfterLastCodeAge - 1,
5800 kCodeAgeCount = kAfterLastCodeAge - kNotExecutedCodeAge - 1,
5801 kIsOldCodeAge = kSexagenarianCodeAge,
5802 kPreAgedCodeAge = kIsOldCodeAge - 1
5803 };
5804 #undef DECLARE_CODE_AGE_ENUM
5805
5806 // Code aging. Indicates how many full GCs this code has survived without
5807 // being entered through the prologue. Used to determine when it is
5808 // relatively safe to flush this code object and replace it with the lazy
5809 // compilation stub.
5810 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5811 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
5812 void MakeOlder(MarkingParity);
5813 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5814 bool IsOld();
5815 Age GetAge();
5816 // Gets the raw code age, including psuedo code-age values such as
5817 // kNotExecutedCodeAge and kExecutedOnceCodeAge.
5818 Age GetRawAge();
GetPreAgedCodeAgeStub(Isolate * isolate)5819 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5820 return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5821 }
5822
5823 void PrintDeoptLocation(FILE* out, int bailout_id);
5824 bool CanDeoptAt(Address pc);
5825
5826 #ifdef VERIFY_HEAP
5827 void VerifyEmbeddedObjectsDependency();
5828 #endif
5829
CanContainWeakObjects()5830 inline bool CanContainWeakObjects() {
5831 return is_optimized_code() || is_weak_stub();
5832 }
5833
IsWeakObject(Object * object)5834 inline bool IsWeakObject(Object* object) {
5835 return (is_optimized_code() && IsWeakObjectInOptimizedCode(object)) ||
5836 (is_weak_stub() && IsWeakObjectInIC(object));
5837 }
5838
5839 static inline bool IsWeakObjectInOptimizedCode(Object* object);
5840 static inline bool IsWeakObjectInIC(Object* object);
5841
5842 // Max loop nesting marker used to postpose OSR. We don't take loop
5843 // nesting that is deeper than 5 levels into account.
5844 static const int kMaxLoopNestingMarker = 6;
5845
5846 // Layout description.
5847 static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
5848 static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
5849 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
5850 static const int kDeoptimizationDataOffset =
5851 kHandlerTableOffset + kPointerSize;
5852 static const int kTypeFeedbackInfoOffset =
5853 kDeoptimizationDataOffset + kPointerSize;
5854 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5855 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
5856 static const int kICAgeOffset =
5857 kGCMetadataOffset + kPointerSize;
5858 static const int kFlagsOffset = kICAgeOffset + kIntSize;
5859 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5860 static const int kKindSpecificFlags2Offset =
5861 kKindSpecificFlags1Offset + kIntSize;
5862 // Note: We might be able to squeeze this into the flags above.
5863 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
5864 static const int kConstantPoolOffset = kPrologueOffset + kPointerSize;
5865
5866 static const int kHeaderPaddingStart = kConstantPoolOffset + kIntSize;
5867
5868 // Add padding to align the instruction start following right after
5869 // the Code object header.
5870 static const int kHeaderSize =
5871 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
5872
5873 // Byte offsets within kKindSpecificFlags1Offset.
5874 static const int kOptimizableOffset = kKindSpecificFlags1Offset;
5875
5876 static const int kFullCodeFlags = kOptimizableOffset + 1;
5877 class FullCodeFlagsHasDeoptimizationSupportField:
5878 public BitField<bool, 0, 1> {}; // NOLINT
5879 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
5880 class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
5881
5882 static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1;
5883 static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1;
5884
5885 // Flags layout. BitField<type, shift, size>.
5886 class ICStateField: public BitField<InlineCacheState, 0, 3> {};
5887 class TypeField: public BitField<StubType, 3, 1> {};
5888 class CacheHolderField: public BitField<InlineCacheHolderFlag, 5, 1> {};
5889 class KindField: public BitField<Kind, 6, 4> {};
5890 // TODO(bmeurer): Bit 10 is available for free use. :-)
5891 class ExtraICStateField: public BitField<ExtraICState, 11,
5892 PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT
5893
5894 // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
5895 static const int kStackSlotsFirstBit = 0;
5896 static const int kStackSlotsBitCount = 24;
5897 static const int kHasFunctionCacheFirstBit =
5898 kStackSlotsFirstBit + kStackSlotsBitCount;
5899 static const int kHasFunctionCacheBitCount = 1;
5900 static const int kMarkedForDeoptimizationFirstBit =
5901 kStackSlotsFirstBit + kStackSlotsBitCount + 1;
5902 static const int kMarkedForDeoptimizationBitCount = 1;
5903 static const int kWeakStubFirstBit =
5904 kMarkedForDeoptimizationFirstBit + kMarkedForDeoptimizationBitCount;
5905 static const int kWeakStubBitCount = 1;
5906 static const int kInvalidatedWeakStubFirstBit =
5907 kWeakStubFirstBit + kWeakStubBitCount;
5908 static const int kInvalidatedWeakStubBitCount = 1;
5909
5910 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
5911 STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
5912 STATIC_ASSERT(kInvalidatedWeakStubFirstBit +
5913 kInvalidatedWeakStubBitCount <= 32);
5914
5915 class StackSlotsField: public BitField<int,
5916 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
5917 class HasFunctionCacheField: public BitField<bool,
5918 kHasFunctionCacheFirstBit, kHasFunctionCacheBitCount> {}; // NOLINT
5919 class MarkedForDeoptimizationField: public BitField<bool,
5920 kMarkedForDeoptimizationFirstBit,
5921 kMarkedForDeoptimizationBitCount> {}; // NOLINT
5922 class WeakStubField: public BitField<bool,
5923 kWeakStubFirstBit,
5924 kWeakStubBitCount> {}; // NOLINT
5925 class InvalidatedWeakStubField: public BitField<bool,
5926 kInvalidatedWeakStubFirstBit,
5927 kInvalidatedWeakStubBitCount> {}; // NOLINT
5928
5929 // KindSpecificFlags2 layout (ALL)
5930 static const int kIsCrankshaftedBit = 0;
5931 class IsCrankshaftedField: public BitField<bool,
5932 kIsCrankshaftedBit, 1> {}; // NOLINT
5933
5934 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5935 static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
5936 static const int kSafepointTableOffsetFirstBit =
5937 kStubMajorKeyFirstBit + kStubMajorKeyBits;
5938 static const int kSafepointTableOffsetBitCount = 24;
5939
5940 STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
5941 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5942 kSafepointTableOffsetBitCount <= 32);
5943 STATIC_ASSERT(1 + kStubMajorKeyBits +
5944 kSafepointTableOffsetBitCount <= 32);
5945
5946 class SafepointTableOffsetField: public BitField<int,
5947 kSafepointTableOffsetFirstBit,
5948 kSafepointTableOffsetBitCount> {}; // NOLINT
5949 class StubMajorKeyField: public BitField<int,
5950 kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT
5951
5952 // KindSpecificFlags2 layout (FUNCTION)
5953 class BackEdgeTableOffsetField: public BitField<int,
5954 kIsCrankshaftedBit + 1, 29> {}; // NOLINT
5955 class BackEdgesPatchedForOSRField: public BitField<bool,
5956 kIsCrankshaftedBit + 1 + 29, 1> {}; // NOLINT
5957
5958 static const int kArgumentsBits = 16;
5959 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
5960
5961 // This constant should be encodable in an ARM instruction.
5962 static const int kFlagsNotUsedInLookup =
5963 TypeField::kMask | CacheHolderField::kMask;
5964
5965 private:
5966 friend class RelocIterator;
5967 friend class Deoptimizer; // For FindCodeAgeSequence.
5968
5969 void ClearInlineCaches(Kind* kind);
5970
5971 // Code aging
5972 byte* FindCodeAgeSequence();
5973 static void GetCodeAgeAndParity(Code* code, Age* age,
5974 MarkingParity* parity);
5975 static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
5976 MarkingParity* parity);
5977 static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5978
5979 // Code aging -- platform-specific
5980 static void PatchPlatformCodeAge(Isolate* isolate,
5981 byte* sequence, Age age,
5982 MarkingParity parity);
5983
5984 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5985 };
5986
5987
5988 class CompilationInfo;
5989
5990 // This class describes the layout of dependent codes array of a map. The
5991 // array is partitioned into several groups of dependent codes. Each group
5992 // contains codes with the same dependency on the map. The array has the
5993 // following layout for n dependency groups:
5994 //
5995 // +----+----+-----+----+---------+----------+-----+---------+-----------+
5996 // | C1 | C2 | ... | Cn | group 1 | group 2 | ... | group n | undefined |
5997 // +----+----+-----+----+---------+----------+-----+---------+-----------+
5998 //
5999 // The first n elements are Smis, each of them specifies the number of codes
6000 // in the corresponding group. The subsequent elements contain grouped code
6001 // objects. The suffix of the array can be filled with the undefined value if
6002 // the number of codes is less than the length of the array. The order of the
6003 // code objects within a group is not preserved.
6004 //
6005 // All code indexes used in the class are counted starting from the first
6006 // code object of the first group. In other words, code index 0 corresponds
6007 // to array index n = kCodesStartIndex.
6008
6009 class DependentCode: public FixedArray {
6010 public:
6011 enum DependencyGroup {
6012 // Group of IC stubs that weakly embed this map and depend on being
6013 // invalidated when the map is garbage collected. Dependent IC stubs form
6014 // a linked list. This group stores only the head of the list. This means
6015 // that the number_of_entries(kWeakICGroup) is 0 or 1.
6016 kWeakICGroup,
6017 // Group of code that weakly embed this map and depend on being
6018 // deoptimized when the map is garbage collected.
6019 kWeakCodeGroup,
6020 // Group of code that embed a transition to this map, and depend on being
6021 // deoptimized when the transition is replaced by a new version.
6022 kTransitionGroup,
6023 // Group of code that omit run-time prototype checks for prototypes
6024 // described by this map. The group is deoptimized whenever an object
6025 // described by this map changes shape (and transitions to a new map),
6026 // possibly invalidating the assumptions embedded in the code.
6027 kPrototypeCheckGroup,
6028 // Group of code that depends on elements not being added to objects with
6029 // this map.
6030 kElementsCantBeAddedGroup,
6031 // Group of code that depends on global property values in property cells
6032 // not being changed.
6033 kPropertyCellChangedGroup,
6034 // Group of code that omit run-time type checks for the field(s) introduced
6035 // by this map.
6036 kFieldTypeGroup,
6037 // Group of code that omit run-time type checks for initial maps of
6038 // constructors.
6039 kInitialMapChangedGroup,
6040 // Group of code that depends on tenuring information in AllocationSites
6041 // not being changed.
6042 kAllocationSiteTenuringChangedGroup,
6043 // Group of code that depends on element transition information in
6044 // AllocationSites not being changed.
6045 kAllocationSiteTransitionChangedGroup,
6046 kGroupCount = kAllocationSiteTransitionChangedGroup + 1
6047 };
6048
6049 // Array for holding the index of the first code object of each group.
6050 // The last element stores the total number of code objects.
6051 class GroupStartIndexes {
6052 public:
6053 explicit GroupStartIndexes(DependentCode* entries);
6054 void Recompute(DependentCode* entries);
at(int i)6055 int at(int i) { return start_indexes_[i]; }
number_of_entries()6056 int number_of_entries() { return start_indexes_[kGroupCount]; }
6057 private:
6058 int start_indexes_[kGroupCount + 1];
6059 };
6060
6061 bool Contains(DependencyGroup group, Code* code);
6062 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
6063 DependencyGroup group,
6064 Handle<Object> object);
6065 void UpdateToFinishedCode(DependencyGroup group,
6066 CompilationInfo* info,
6067 Code* code);
6068 void RemoveCompilationInfo(DependentCode::DependencyGroup group,
6069 CompilationInfo* info);
6070
6071 void DeoptimizeDependentCodeGroup(Isolate* isolate,
6072 DependentCode::DependencyGroup group);
6073
6074 bool MarkCodeForDeoptimization(Isolate* isolate,
6075 DependentCode::DependencyGroup group);
6076 void AddToDependentICList(Handle<Code> stub);
6077
6078 // The following low-level accessors should only be used by this class
6079 // and the mark compact collector.
6080 inline int number_of_entries(DependencyGroup group);
6081 inline void set_number_of_entries(DependencyGroup group, int value);
6082 inline bool is_code_at(int i);
6083 inline Code* code_at(int i);
6084 inline CompilationInfo* compilation_info_at(int i);
6085 inline void set_object_at(int i, Object* object);
6086 inline Object** slot_at(int i);
6087 inline Object* object_at(int i);
6088 inline void clear_at(int i);
6089 inline void copy(int from, int to);
6090 static inline DependentCode* cast(Object* object);
6091
6092 static DependentCode* ForObject(Handle<HeapObject> object,
6093 DependencyGroup group);
6094
6095 private:
6096 // Make a room at the end of the given group by moving out the first
6097 // code objects of the subsequent groups.
6098 inline void ExtendGroup(DependencyGroup group);
6099 static const int kCodesStartIndex = kGroupCount;
6100 };
6101
6102
6103 // All heap objects have a Map that describes their structure.
6104 // A Map contains information about:
6105 // - Size information about the object
6106 // - How to iterate over an object (for garbage collection)
6107 class Map: public HeapObject {
6108 public:
6109 // Instance size.
6110 // Size in bytes or kVariableSizeSentinel if instances do not have
6111 // a fixed size.
6112 inline int instance_size();
6113 inline void set_instance_size(int value);
6114
6115 // Count of properties allocated in the object.
6116 inline int inobject_properties();
6117 inline void set_inobject_properties(int value);
6118
6119 // Count of property fields pre-allocated in the object when first allocated.
6120 inline int pre_allocated_property_fields();
6121 inline void set_pre_allocated_property_fields(int value);
6122
6123 // Instance type.
6124 inline InstanceType instance_type();
6125 inline void set_instance_type(InstanceType value);
6126
6127 // Tells how many unused property fields are available in the
6128 // instance (only used for JSObject in fast mode).
6129 inline int unused_property_fields();
6130 inline void set_unused_property_fields(int value);
6131
6132 // Bit field.
6133 inline byte bit_field();
6134 inline void set_bit_field(byte value);
6135
6136 // Bit field 2.
6137 inline byte bit_field2();
6138 inline void set_bit_field2(byte value);
6139
6140 // Bit field 3.
6141 inline uint32_t bit_field3();
6142 inline void set_bit_field3(uint32_t bits);
6143
6144 class EnumLengthBits: public BitField<int,
6145 0, kDescriptorIndexBitCount> {}; // NOLINT
6146 class NumberOfOwnDescriptorsBits: public BitField<int,
6147 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
6148 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
6149 class IsShared: public BitField<bool, 20, 1> {};
6150 class DictionaryMap: public BitField<bool, 21, 1> {};
6151 class OwnsDescriptors: public BitField<bool, 22, 1> {};
6152 class HasInstanceCallHandler: public BitField<bool, 23, 1> {};
6153 class Deprecated: public BitField<bool, 24, 1> {};
6154 class IsFrozen: public BitField<bool, 25, 1> {};
6155 class IsUnstable: public BitField<bool, 26, 1> {};
6156 class IsMigrationTarget: public BitField<bool, 27, 1> {};
6157 class DoneInobjectSlackTracking: public BitField<bool, 28, 1> {};
6158 // Keep this bit field at the very end for better code in
6159 // Builtins::kJSConstructStubGeneric stub.
6160 class ConstructionCount: public BitField<int, 29, 3> {};
6161
6162 // Tells whether the object in the prototype property will be used
6163 // for instances created from this function. If the prototype
6164 // property is set to a value that is not a JSObject, the prototype
6165 // property will not be used to create instances of the function.
6166 // See ECMA-262, 13.2.2.
6167 inline void set_non_instance_prototype(bool value);
6168 inline bool has_non_instance_prototype();
6169
6170 // Tells whether function has special prototype property. If not, prototype
6171 // property will not be created when accessed (will return undefined),
6172 // and construction from this function will not be allowed.
6173 inline void set_function_with_prototype(bool value);
6174 inline bool function_with_prototype();
6175
6176 // Tells whether the instance with this map should be ignored by the
6177 // Object.getPrototypeOf() function and the __proto__ accessor.
set_is_hidden_prototype()6178 inline void set_is_hidden_prototype() {
6179 set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
6180 }
6181
is_hidden_prototype()6182 inline bool is_hidden_prototype() {
6183 return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
6184 }
6185
6186 // Records and queries whether the instance has a named interceptor.
set_has_named_interceptor()6187 inline void set_has_named_interceptor() {
6188 set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
6189 }
6190
has_named_interceptor()6191 inline bool has_named_interceptor() {
6192 return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
6193 }
6194
6195 // Records and queries whether the instance has an indexed interceptor.
set_has_indexed_interceptor()6196 inline void set_has_indexed_interceptor() {
6197 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
6198 }
6199
has_indexed_interceptor()6200 inline bool has_indexed_interceptor() {
6201 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
6202 }
6203
6204 // Tells whether the instance is undetectable.
6205 // An undetectable object is a special class of JSObject: 'typeof' operator
6206 // returns undefined, ToBoolean returns false. Otherwise it behaves like
6207 // a normal JS object. It is useful for implementing undetectable
6208 // document.all in Firefox & Safari.
6209 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
set_is_undetectable()6210 inline void set_is_undetectable() {
6211 set_bit_field(bit_field() | (1 << kIsUndetectable));
6212 }
6213
is_undetectable()6214 inline bool is_undetectable() {
6215 return ((1 << kIsUndetectable) & bit_field()) != 0;
6216 }
6217
6218 // Tells whether the instance has a call-as-function handler.
set_is_observed()6219 inline void set_is_observed() {
6220 set_bit_field(bit_field() | (1 << kIsObserved));
6221 }
6222
is_observed()6223 inline bool is_observed() {
6224 return ((1 << kIsObserved) & bit_field()) != 0;
6225 }
6226
6227 inline void set_is_extensible(bool value);
6228 inline bool is_extensible();
6229
set_elements_kind(ElementsKind elements_kind)6230 inline void set_elements_kind(ElementsKind elements_kind) {
6231 ASSERT(elements_kind < kElementsKindCount);
6232 ASSERT(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
6233 set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
6234 ASSERT(this->elements_kind() == elements_kind);
6235 }
6236
elements_kind()6237 inline ElementsKind elements_kind() {
6238 return Map::ElementsKindBits::decode(bit_field2());
6239 }
6240
6241 // Tells whether the instance has fast elements that are only Smis.
has_fast_smi_elements()6242 inline bool has_fast_smi_elements() {
6243 return IsFastSmiElementsKind(elements_kind());
6244 }
6245
6246 // Tells whether the instance has fast elements.
has_fast_object_elements()6247 inline bool has_fast_object_elements() {
6248 return IsFastObjectElementsKind(elements_kind());
6249 }
6250
has_fast_smi_or_object_elements()6251 inline bool has_fast_smi_or_object_elements() {
6252 return IsFastSmiOrObjectElementsKind(elements_kind());
6253 }
6254
has_fast_double_elements()6255 inline bool has_fast_double_elements() {
6256 return IsFastDoubleElementsKind(elements_kind());
6257 }
6258
has_fast_elements()6259 inline bool has_fast_elements() {
6260 return IsFastElementsKind(elements_kind());
6261 }
6262
has_sloppy_arguments_elements()6263 inline bool has_sloppy_arguments_elements() {
6264 return elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
6265 }
6266
has_external_array_elements()6267 inline bool has_external_array_elements() {
6268 return IsExternalArrayElementsKind(elements_kind());
6269 }
6270
has_fixed_typed_array_elements()6271 inline bool has_fixed_typed_array_elements() {
6272 return IsFixedTypedArrayElementsKind(elements_kind());
6273 }
6274
has_dictionary_elements()6275 inline bool has_dictionary_elements() {
6276 return IsDictionaryElementsKind(elements_kind());
6277 }
6278
has_slow_elements_kind()6279 inline bool has_slow_elements_kind() {
6280 return elements_kind() == DICTIONARY_ELEMENTS
6281 || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
6282 }
6283
6284 static bool IsValidElementsTransition(ElementsKind from_kind,
6285 ElementsKind to_kind);
6286
6287 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
6288 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
6289 bool DictionaryElementsInPrototypeChainOnly();
6290
6291 inline bool HasTransitionArray();
6292 inline bool HasElementsTransition();
6293 inline Map* elements_transition_map();
6294 static Handle<TransitionArray> SetElementsTransitionMap(
6295 Handle<Map> map, Handle<Map> transitioned_map);
6296 inline Map* GetTransition(int transition_index);
6297 inline int SearchTransition(Name* name);
6298 inline FixedArrayBase* GetInitialElements();
6299
6300 DECL_ACCESSORS(transitions, TransitionArray)
6301
6302 Map* FindRootMap();
6303 Map* FindFieldOwner(int descriptor);
6304
6305 inline int GetInObjectPropertyOffset(int index);
6306
6307 int NumberOfFields();
6308
6309 bool InstancesNeedRewriting(Map* target,
6310 int target_number_of_fields,
6311 int target_inobject,
6312 int target_unused);
6313 static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
6314 static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> type1,
6315 Handle<HeapType> type2,
6316 Isolate* isolate)
6317 V8_WARN_UNUSED_RESULT;
6318 static void GeneralizeFieldType(Handle<Map> map,
6319 int modify_index,
6320 Handle<HeapType> new_field_type);
6321 static Handle<Map> GeneralizeRepresentation(
6322 Handle<Map> map,
6323 int modify_index,
6324 Representation new_representation,
6325 Handle<HeapType> new_field_type,
6326 StoreMode store_mode);
6327 static Handle<Map> CopyGeneralizeAllRepresentations(
6328 Handle<Map> map,
6329 int modify_index,
6330 StoreMode store_mode,
6331 PropertyAttributes attributes,
6332 const char* reason);
6333 static Handle<Map> CopyGeneralizeAllRepresentations(
6334 Handle<Map> map,
6335 int modify_index,
6336 StoreMode store_mode,
6337 const char* reason);
6338
6339 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);
6340
6341 // Returns the constructor name (the name (possibly, inferred name) of the
6342 // function that was used to instantiate the object).
6343 String* constructor_name();
6344
6345 // Tells whether the map is shared between objects that may have different
6346 // behavior. If true, the map should never be modified, instead a clone
6347 // should be created and modified.
6348 inline void set_is_shared(bool value);
6349 inline bool is_shared();
6350
6351 // Tells whether the map is used for JSObjects in dictionary mode (ie
6352 // normalized objects, ie objects for which HasFastProperties returns false).
6353 // A map can never be used for both dictionary mode and fast mode JSObjects.
6354 // False by default and for HeapObjects that are not JSObjects.
6355 inline void set_dictionary_map(bool value);
6356 inline bool is_dictionary_map();
6357
6358 // Tells whether the instance needs security checks when accessing its
6359 // properties.
6360 inline void set_is_access_check_needed(bool access_check_needed);
6361 inline bool is_access_check_needed();
6362
6363 // Returns true if map has a non-empty stub code cache.
6364 inline bool has_code_cache();
6365
6366 // [prototype]: implicit prototype object.
6367 DECL_ACCESSORS(prototype, Object)
6368
6369 // [constructor]: points back to the function responsible for this map.
6370 DECL_ACCESSORS(constructor, Object)
6371
6372 // [instance descriptors]: describes the object.
6373 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
6374 inline void InitializeDescriptors(DescriptorArray* descriptors);
6375
6376 // [stub cache]: contains stubs compiled for this map.
6377 DECL_ACCESSORS(code_cache, Object)
6378
6379 // [dependent code]: list of optimized codes that weakly embed this map.
6380 DECL_ACCESSORS(dependent_code, DependentCode)
6381
6382 // [back pointer]: points back to the parent map from which a transition
6383 // leads to this map. The field overlaps with prototype transitions and the
6384 // back pointer will be moved into the prototype transitions array if
6385 // required.
6386 inline Object* GetBackPointer();
6387 inline void SetBackPointer(Object* value,
6388 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
6389 inline void init_back_pointer(Object* undefined);
6390
6391 // [prototype transitions]: cache of prototype transitions.
6392 // Prototype transition is a transition that happens
6393 // when we change object's prototype to a new one.
6394 // Cache format:
6395 // 0: finger - index of the first free cell in the cache
6396 // 1: back pointer that overlaps with prototype transitions field.
6397 // 2 + 2 * i: prototype
6398 // 3 + 2 * i: target map
6399 inline FixedArray* GetPrototypeTransitions();
6400 inline bool HasPrototypeTransitions();
6401
6402 static const int kProtoTransitionHeaderSize = 1;
6403 static const int kProtoTransitionNumberOfEntriesOffset = 0;
6404 static const int kProtoTransitionElementsPerEntry = 2;
6405 static const int kProtoTransitionPrototypeOffset = 0;
6406 static const int kProtoTransitionMapOffset = 1;
6407
NumberOfProtoTransitions()6408 inline int NumberOfProtoTransitions() {
6409 FixedArray* cache = GetPrototypeTransitions();
6410 if (cache->length() == 0) return 0;
6411 return
6412 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
6413 }
6414
SetNumberOfProtoTransitions(int value)6415 inline void SetNumberOfProtoTransitions(int value) {
6416 FixedArray* cache = GetPrototypeTransitions();
6417 ASSERT(cache->length() != 0);
6418 cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value));
6419 }
6420
6421 // Lookup in the map's instance descriptors and fill out the result
6422 // with the given holder if the name is found. The holder may be
6423 // NULL when this function is used from the compiler.
6424 inline void LookupDescriptor(JSObject* holder,
6425 Name* name,
6426 LookupResult* result);
6427
6428 inline void LookupTransition(JSObject* holder,
6429 Name* name,
6430 LookupResult* result);
6431
6432 inline PropertyDetails GetLastDescriptorDetails();
6433
6434 // The size of transition arrays are limited so they do not end up in large
6435 // object space. Otherwise ClearNonLiveTransitions would leak memory while
6436 // applying in-place right trimming.
6437 inline bool CanHaveMoreTransitions();
6438
LastAdded()6439 int LastAdded() {
6440 int number_of_own_descriptors = NumberOfOwnDescriptors();
6441 ASSERT(number_of_own_descriptors > 0);
6442 return number_of_own_descriptors - 1;
6443 }
6444
NumberOfOwnDescriptors()6445 int NumberOfOwnDescriptors() {
6446 return NumberOfOwnDescriptorsBits::decode(bit_field3());
6447 }
6448
SetNumberOfOwnDescriptors(int number)6449 void SetNumberOfOwnDescriptors(int number) {
6450 ASSERT(number <= instance_descriptors()->number_of_descriptors());
6451 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
6452 }
6453
6454 inline Cell* RetrieveDescriptorsPointer();
6455
EnumLength()6456 int EnumLength() {
6457 return EnumLengthBits::decode(bit_field3());
6458 }
6459
SetEnumLength(int length)6460 void SetEnumLength(int length) {
6461 if (length != kInvalidEnumCacheSentinel) {
6462 ASSERT(length >= 0);
6463 ASSERT(length == 0 || instance_descriptors()->HasEnumCache());
6464 ASSERT(length <= NumberOfOwnDescriptors());
6465 }
6466 set_bit_field3(EnumLengthBits::update(bit_field3(), length));
6467 }
6468
6469 inline bool owns_descriptors();
6470 inline void set_owns_descriptors(bool is_shared);
6471 inline bool has_instance_call_handler();
6472 inline void set_has_instance_call_handler();
6473 inline void freeze();
6474 inline bool is_frozen();
6475 inline void mark_unstable();
6476 inline bool is_stable();
6477 inline void set_migration_target(bool value);
6478 inline bool is_migration_target();
6479 inline void set_done_inobject_slack_tracking(bool value);
6480 inline bool done_inobject_slack_tracking();
6481 inline void set_construction_count(int value);
6482 inline int construction_count();
6483 inline void deprecate();
6484 inline bool is_deprecated();
6485 inline bool CanBeDeprecated();
6486 // Returns a non-deprecated version of the input. If the input was not
6487 // deprecated, it is directly returned. Otherwise, the non-deprecated version
6488 // is found by re-transitioning from the root of the transition tree using the
6489 // descriptor array of the map. Returns NULL if no updated map is found.
6490 // This method also applies any pending migrations along the prototype chain.
6491 static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map)
6492 V8_WARN_UNUSED_RESULT;
6493 // Same as above, but does not touch the prototype chain.
6494 static MaybeHandle<Map> CurrentMapForDeprecatedInternal(Handle<Map> map)
6495 V8_WARN_UNUSED_RESULT;
6496
6497 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
6498 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
6499 Descriptor* descriptor,
6500 TransitionFlag flag);
6501
6502 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
6503 Handle<Map> map,
6504 Handle<Name> name,
6505 Handle<HeapType> type,
6506 PropertyAttributes attributes,
6507 Representation representation,
6508 TransitionFlag flag);
6509
6510 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
6511 Handle<Map> map,
6512 Handle<Name> name,
6513 Handle<Object> constant,
6514 PropertyAttributes attributes,
6515 TransitionFlag flag);
6516
6517 // Returns a new map with all transitions dropped from the given map and
6518 // the ElementsKind set.
6519 static Handle<Map> TransitionElementsTo(Handle<Map> map,
6520 ElementsKind to_kind);
6521
6522 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
6523
6524 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
6525 ElementsKind kind,
6526 TransitionFlag flag);
6527
6528 static Handle<Map> CopyForObserved(Handle<Map> map);
6529
6530 static Handle<Map> CopyForFreeze(Handle<Map> map);
6531
6532 inline void AppendDescriptor(Descriptor* desc);
6533
6534 // Returns a copy of the map, with all transitions dropped from the
6535 // instance descriptors.
6536 static Handle<Map> Copy(Handle<Map> map);
6537 static Handle<Map> Create(Handle<JSFunction> constructor,
6538 int extra_inobject_properties);
6539
6540 // Returns the next free property index (only valid for FAST MODE).
6541 int NextFreePropertyIndex();
6542
6543 // Returns the number of properties described in instance_descriptors
6544 // filtering out properties with the specified attributes.
6545 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
6546 PropertyAttributes filter = NONE);
6547
6548 // Returns the number of slots allocated for the initial properties
6549 // backing storage for instances of this map.
InitialPropertiesLength()6550 int InitialPropertiesLength() {
6551 return pre_allocated_property_fields() + unused_property_fields() -
6552 inobject_properties();
6553 }
6554
6555 // Casting.
6556 static inline Map* cast(Object* obj);
6557
6558 // Code cache operations.
6559
6560 // Clears the code cache.
6561 inline void ClearCodeCache(Heap* heap);
6562
6563 // Update code cache.
6564 static void UpdateCodeCache(Handle<Map> map,
6565 Handle<Name> name,
6566 Handle<Code> code);
6567
6568 // Extend the descriptor array of the map with the list of descriptors.
6569 // In case of duplicates, the latest descriptor is used.
6570 static void AppendCallbackDescriptors(Handle<Map> map,
6571 Handle<Object> descriptors);
6572
6573 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
6574
6575 // Returns the found code or undefined if absent.
6576 Object* FindInCodeCache(Name* name, Code::Flags flags);
6577
6578 // Returns the non-negative index of the code object if it is in the
6579 // cache and -1 otherwise.
6580 int IndexInCodeCache(Object* name, Code* code);
6581
6582 // Removes a code object from the code cache at the given index.
6583 void RemoveFromCodeCache(Name* name, Code* code, int index);
6584
6585 // Set all map transitions from this map to dead maps to null. Also clear
6586 // back pointers in transition targets so that we do not process this map
6587 // again while following back pointers.
6588 void ClearNonLiveTransitions(Heap* heap);
6589
6590 // Computes a hash value for this map, to be used in HashTables and such.
6591 int Hash();
6592
6593 // Returns the map that this map transitions to if its elements_kind
6594 // is changed to |elements_kind|, or NULL if no such map is cached yet.
6595 // |safe_to_add_transitions| is set to false if adding transitions is not
6596 // allowed.
6597 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6598
6599 // Returns the transitioned map for this map with the most generic
6600 // elements_kind that's found in |candidates|, or null handle if no match is
6601 // found at all.
6602 Handle<Map> FindTransitionedMap(MapHandleList* candidates);
6603 Map* FindTransitionedMap(MapList* candidates);
6604
CanTransition()6605 bool CanTransition() {
6606 // Only JSObject and subtypes have map transitions and back pointers.
6607 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
6608 return instance_type() >= FIRST_JS_OBJECT_TYPE;
6609 }
6610
IsJSObjectMap()6611 bool IsJSObjectMap() {
6612 return instance_type() >= FIRST_JS_OBJECT_TYPE;
6613 }
IsJSProxyMap()6614 bool IsJSProxyMap() {
6615 InstanceType type = instance_type();
6616 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
6617 }
IsJSGlobalProxyMap()6618 bool IsJSGlobalProxyMap() {
6619 return instance_type() == JS_GLOBAL_PROXY_TYPE;
6620 }
IsJSGlobalObjectMap()6621 bool IsJSGlobalObjectMap() {
6622 return instance_type() == JS_GLOBAL_OBJECT_TYPE;
6623 }
IsGlobalObjectMap()6624 bool IsGlobalObjectMap() {
6625 const InstanceType type = instance_type();
6626 return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE;
6627 }
6628
6629 inline bool CanOmitMapChecks();
6630
6631 static void AddDependentCompilationInfo(Handle<Map> map,
6632 DependentCode::DependencyGroup group,
6633 CompilationInfo* info);
6634
6635 static void AddDependentCode(Handle<Map> map,
6636 DependentCode::DependencyGroup group,
6637 Handle<Code> code);
6638 static void AddDependentIC(Handle<Map> map,
6639 Handle<Code> stub);
6640
6641 bool IsMapInArrayPrototypeChain();
6642
6643 // Dispatched behavior.
6644 DECLARE_PRINTER(Map)
6645 DECLARE_VERIFIER(Map)
6646
6647 #ifdef VERIFY_HEAP
6648 void SharedMapVerify();
6649 void VerifyOmittedMapChecks();
6650 #endif
6651
6652 inline int visitor_id();
6653 inline void set_visitor_id(int visitor_id);
6654
6655 typedef void (*TraverseCallback)(Map* map, void* data);
6656
6657 void TraverseTransitionTree(TraverseCallback callback, void* data);
6658
6659 // When you set the prototype of an object using the __proto__ accessor you
6660 // need a new map for the object (the prototype is stored in the map). In
6661 // order not to multiply maps unnecessarily we store these as transitions in
6662 // the original map. That way we can transition to the same map if the same
6663 // prototype is set, rather than creating a new map every time. The
6664 // transitions are in the form of a map where the keys are prototype objects
6665 // and the values are the maps the are transitioned to.
6666 static const int kMaxCachedPrototypeTransitions = 256;
6667 static Handle<Map> TransitionToPrototype(Handle<Map> map,
6668 Handle<Object> prototype);
6669
6670 static const int kMaxPreAllocatedPropertyFields = 255;
6671
6672 // Layout description.
6673 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6674 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
6675 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
6676 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
6677 static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
6678 // Storage for the transition array is overloaded to directly contain a back
6679 // pointer if unused. When the map has transitions, the back pointer is
6680 // transferred to the transition array and accessed through an extra
6681 // indirection.
6682 static const int kTransitionsOrBackPointerOffset =
6683 kConstructorOffset + kPointerSize;
6684 static const int kDescriptorsOffset =
6685 kTransitionsOrBackPointerOffset + kPointerSize;
6686 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
6687 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
6688 static const int kSize = kDependentCodeOffset + kPointerSize;
6689
6690 // Layout of pointer fields. Heap iteration code relies on them
6691 // being continuously allocated.
6692 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
6693 static const int kPointerFieldsEndOffset = kSize;
6694
6695 // Byte offsets within kInstanceSizesOffset.
6696 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
6697 static const int kInObjectPropertiesByte = 1;
6698 static const int kInObjectPropertiesOffset =
6699 kInstanceSizesOffset + kInObjectPropertiesByte;
6700 static const int kPreAllocatedPropertyFieldsByte = 2;
6701 static const int kPreAllocatedPropertyFieldsOffset =
6702 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
6703 static const int kVisitorIdByte = 3;
6704 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
6705
6706 // Byte offsets within kInstanceAttributesOffset attributes.
6707 #if V8_TARGET_LITTLE_ENDIAN
6708 // Order instance type and bit field together such that they can be loaded
6709 // together as a 16-bit word with instance type in the lower 8 bits regardless
6710 // of endianess.
6711 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
6712 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6713 #else
6714 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6715 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6716 #endif
6717 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
6718 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
6719
6720 STATIC_ASSERT(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
6721
6722 // Bit positions for bit field.
6723 static const int kHasNonInstancePrototype = 0;
6724 static const int kIsHiddenPrototype = 1;
6725 static const int kHasNamedInterceptor = 2;
6726 static const int kHasIndexedInterceptor = 3;
6727 static const int kIsUndetectable = 4;
6728 static const int kIsObserved = 5;
6729 static const int kIsAccessCheckNeeded = 6;
6730 class FunctionWithPrototype: public BitField<bool, 7, 1> {};
6731
6732 // Bit positions for bit field 2
6733 static const int kIsExtensible = 0;
6734 static const int kStringWrapperSafeForDefaultValueOf = 1;
6735 // Currently bit 2 is not used.
6736 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
6737
6738 // Derived values from bit field 2
6739 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
6740 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6741 static const int8_t kMaximumBitField2FastSmiElementValue =
6742 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6743 Map::ElementsKindBits::kShift) - 1;
6744 static const int8_t kMaximumBitField2FastHoleyElementValue =
6745 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6746 Map::ElementsKindBits::kShift) - 1;
6747 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6748 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6749 Map::ElementsKindBits::kShift) - 1;
6750
6751 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6752 kPointerFieldsEndOffset,
6753 kSize> BodyDescriptor;
6754
6755 // Compares this map to another to see if they describe equivalent objects.
6756 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6757 // it had exactly zero inobject properties.
6758 // The "shared" flags of both this map and |other| are ignored.
6759 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6760
6761 private:
6762 bool EquivalentToForTransition(Map* other);
6763 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6764 static Handle<Map> ShareDescriptor(Handle<Map> map,
6765 Handle<DescriptorArray> descriptors,
6766 Descriptor* descriptor);
6767 static Handle<Map> CopyInstallDescriptors(
6768 Handle<Map> map,
6769 int new_descriptor,
6770 Handle<DescriptorArray> descriptors);
6771 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6772 Descriptor* descriptor,
6773 TransitionFlag flag);
6774 static Handle<Map> CopyReplaceDescriptors(
6775 Handle<Map> map,
6776 Handle<DescriptorArray> descriptors,
6777 TransitionFlag flag,
6778 MaybeHandle<Name> maybe_name,
6779 SimpleTransitionFlag simple_flag = FULL_TRANSITION);
6780 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6781 Handle<DescriptorArray> descriptors,
6782 Descriptor* descriptor,
6783 int index,
6784 TransitionFlag flag);
6785
6786 static Handle<Map> CopyNormalized(Handle<Map> map,
6787 PropertyNormalizationMode mode,
6788 NormalizedMapSharingMode sharing);
6789
6790 // Fires when the layout of an object with a leaf map changes.
6791 // This includes adding transitions to the leaf map or changing
6792 // the descriptor array.
6793 inline void NotifyLeafMapLayoutChange();
6794
6795 static Handle<Map> TransitionElementsToSlow(Handle<Map> object,
6796 ElementsKind to_kind);
6797
6798 // Zaps the contents of backing data structures. Note that the
6799 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
6800 // holding weak references when incremental marking is used, because it also
6801 // iterates over objects that are otherwise unreachable.
6802 // In general we only want to call these functions in release mode when
6803 // heap verification is turned on.
6804 void ZapPrototypeTransitions();
6805 void ZapTransitions();
6806
6807 void DeprecateTransitionTree();
6808 void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
6809
6810 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
6811
6812 void UpdateDescriptor(int descriptor_number, Descriptor* desc);
6813
6814 void PrintGeneralization(FILE* file,
6815 const char* reason,
6816 int modify_index,
6817 int split,
6818 int descriptors,
6819 bool constant_to_field,
6820 Representation old_representation,
6821 Representation new_representation,
6822 HeapType* old_field_type,
6823 HeapType* new_field_type);
6824
6825 static inline void SetPrototypeTransitions(
6826 Handle<Map> map,
6827 Handle<FixedArray> prototype_transitions);
6828
6829 static Handle<Map> GetPrototypeTransition(Handle<Map> map,
6830 Handle<Object> prototype);
6831 static Handle<Map> PutPrototypeTransition(Handle<Map> map,
6832 Handle<Object> prototype,
6833 Handle<Map> target_map);
6834
6835 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6836 };
6837
6838
6839 // An abstract superclass, a marker class really, for simple structure classes.
6840 // It doesn't carry much functionality but allows struct classes to be
6841 // identified in the type system.
6842 class Struct: public HeapObject {
6843 public:
6844 inline void InitializeBody(int object_size);
6845 static inline Struct* cast(Object* that);
6846 };
6847
6848
6849 // A simple one-element struct, useful where smis need to be boxed.
6850 class Box : public Struct {
6851 public:
6852 // [value]: the boxed contents.
6853 DECL_ACCESSORS(value, Object)
6854
6855 static inline Box* cast(Object* obj);
6856
6857 // Dispatched behavior.
6858 DECLARE_PRINTER(Box)
6859 DECLARE_VERIFIER(Box)
6860
6861 static const int kValueOffset = HeapObject::kHeaderSize;
6862 static const int kSize = kValueOffset + kPointerSize;
6863
6864 private:
6865 DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
6866 };
6867
6868
6869 // Script describes a script which has been added to the VM.
6870 class Script: public Struct {
6871 public:
6872 // Script types.
6873 enum Type {
6874 TYPE_NATIVE = 0,
6875 TYPE_EXTENSION = 1,
6876 TYPE_NORMAL = 2
6877 };
6878
6879 // Script compilation types.
6880 enum CompilationType {
6881 COMPILATION_TYPE_HOST = 0,
6882 COMPILATION_TYPE_EVAL = 1
6883 };
6884
6885 // Script compilation state.
6886 enum CompilationState {
6887 COMPILATION_STATE_INITIAL = 0,
6888 COMPILATION_STATE_COMPILED = 1
6889 };
6890
6891 // [source]: the script source.
6892 DECL_ACCESSORS(source, Object)
6893
6894 // [name]: the script name.
6895 DECL_ACCESSORS(name, Object)
6896
6897 // [id]: the script id.
6898 DECL_ACCESSORS(id, Smi)
6899
6900 // [line_offset]: script line offset in resource from where it was extracted.
6901 DECL_ACCESSORS(line_offset, Smi)
6902
6903 // [column_offset]: script column offset in resource from where it was
6904 // extracted.
6905 DECL_ACCESSORS(column_offset, Smi)
6906
6907 // [context_data]: context data for the context this script was compiled in.
6908 DECL_ACCESSORS(context_data, Object)
6909
6910 // [wrapper]: the wrapper cache.
6911 DECL_ACCESSORS(wrapper, Foreign)
6912
6913 // [type]: the script type.
6914 DECL_ACCESSORS(type, Smi)
6915
6916 // [line_ends]: FixedArray of line ends positions.
6917 DECL_ACCESSORS(line_ends, Object)
6918
6919 // [eval_from_shared]: for eval scripts the shared funcion info for the
6920 // function from which eval was called.
6921 DECL_ACCESSORS(eval_from_shared, Object)
6922
6923 // [eval_from_instructions_offset]: the instruction offset in the code for the
6924 // function from which eval was called where eval was called.
6925 DECL_ACCESSORS(eval_from_instructions_offset, Smi)
6926
6927 // [flags]: Holds an exciting bitfield.
6928 DECL_ACCESSORS(flags, Smi)
6929
6930 // [compilation_type]: how the the script was compiled. Encoded in the
6931 // 'flags' field.
6932 inline CompilationType compilation_type();
6933 inline void set_compilation_type(CompilationType type);
6934
6935 // [compilation_state]: determines whether the script has already been
6936 // compiled. Encoded in the 'flags' field.
6937 inline CompilationState compilation_state();
6938 inline void set_compilation_state(CompilationState state);
6939
6940 // [is_shared_cross_origin]: An opaque boolean set by the embedder via
6941 // ScriptOrigin, and used by the embedder to make decisions about the
6942 // script's level of privilege. V8 just passes this through. Encoded in
6943 // the 'flags' field.
6944 DECL_BOOLEAN_ACCESSORS(is_shared_cross_origin)
6945
6946 static inline Script* cast(Object* obj);
6947
6948 // If script source is an external string, check that the underlying
6949 // resource is accessible. Otherwise, always return true.
6950 inline bool HasValidSource();
6951
6952 // Convert code position into column number.
6953 static int GetColumnNumber(Handle<Script> script, int code_pos);
6954
6955 // Convert code position into (zero-based) line number.
6956 // The non-handlified version does not allocate, but may be much slower.
6957 static int GetLineNumber(Handle<Script> script, int code_pos);
6958 int GetLineNumber(int code_pos);
6959
6960 static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
6961
6962 // Init line_ends array with code positions of line ends inside script source.
6963 static void InitLineEnds(Handle<Script> script);
6964
6965 // Get the JS object wrapping the given script; create it if none exists.
6966 static Handle<JSObject> GetWrapper(Handle<Script> script);
6967
6968 // Dispatched behavior.
6969 DECLARE_PRINTER(Script)
6970 DECLARE_VERIFIER(Script)
6971
6972 static const int kSourceOffset = HeapObject::kHeaderSize;
6973 static const int kNameOffset = kSourceOffset + kPointerSize;
6974 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6975 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
6976 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
6977 static const int kWrapperOffset = kContextOffset + kPointerSize;
6978 static const int kTypeOffset = kWrapperOffset + kPointerSize;
6979 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
6980 static const int kIdOffset = kLineEndsOffset + kPointerSize;
6981 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
6982 static const int kEvalFrominstructionsOffsetOffset =
6983 kEvalFromSharedOffset + kPointerSize;
6984 static const int kFlagsOffset =
6985 kEvalFrominstructionsOffsetOffset + kPointerSize;
6986 static const int kSize = kFlagsOffset + kPointerSize;
6987
6988 private:
6989 int GetLineNumberWithArray(int code_pos);
6990
6991 // Bit positions in the flags field.
6992 static const int kCompilationTypeBit = 0;
6993 static const int kCompilationStateBit = 1;
6994 static const int kIsSharedCrossOriginBit = 2;
6995
6996 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6997 };
6998
6999
7000 // List of builtin functions we want to identify to improve code
7001 // generation.
7002 //
7003 // Each entry has a name of a global object property holding an object
7004 // optionally followed by ".prototype", a name of a builtin function
7005 // on the object (the one the id is set for), and a label.
7006 //
7007 // Installation of ids for the selected builtin functions is handled
7008 // by the bootstrapper.
7009 #define FUNCTIONS_WITH_ID_LIST(V) \
7010 V(Array.prototype, indexOf, ArrayIndexOf) \
7011 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
7012 V(Array.prototype, push, ArrayPush) \
7013 V(Array.prototype, pop, ArrayPop) \
7014 V(Array.prototype, shift, ArrayShift) \
7015 V(Function.prototype, apply, FunctionApply) \
7016 V(String.prototype, charCodeAt, StringCharCodeAt) \
7017 V(String.prototype, charAt, StringCharAt) \
7018 V(String, fromCharCode, StringFromCharCode) \
7019 V(Math, floor, MathFloor) \
7020 V(Math, round, MathRound) \
7021 V(Math, ceil, MathCeil) \
7022 V(Math, abs, MathAbs) \
7023 V(Math, log, MathLog) \
7024 V(Math, exp, MathExp) \
7025 V(Math, sqrt, MathSqrt) \
7026 V(Math, pow, MathPow) \
7027 V(Math, max, MathMax) \
7028 V(Math, min, MathMin) \
7029 V(Math, imul, MathImul)
7030
7031 enum BuiltinFunctionId {
7032 kArrayCode,
7033 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
7034 k##name,
7035 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
7036 #undef DECLARE_FUNCTION_ID
7037 // Fake id for a special case of Math.pow. Note, it continues the
7038 // list of math functions.
7039 kMathPowHalf,
7040 // Installed only on --harmony-maths.
7041 kMathClz32
7042 };
7043
7044
7045 // SharedFunctionInfo describes the JSFunction information that can be
7046 // shared by multiple instances of the function.
7047 class SharedFunctionInfo: public HeapObject {
7048 public:
7049 // [name]: Function name.
7050 DECL_ACCESSORS(name, Object)
7051
7052 // [code]: Function code.
7053 DECL_ACCESSORS(code, Code)
7054 inline void ReplaceCode(Code* code);
7055
7056 // [optimized_code_map]: Map from native context to optimized code
7057 // and a shared literals array or Smi(0) if none.
7058 DECL_ACCESSORS(optimized_code_map, Object)
7059
7060 // Returns index i of the entry with the specified context and OSR entry.
7061 // At position i - 1 is the context, position i the code, and i + 1 the
7062 // literals array. Returns -1 when no matching entry is found.
7063 int SearchOptimizedCodeMap(Context* native_context, BailoutId osr_ast_id);
7064
7065 // Installs optimized code from the code map on the given closure. The
7066 // index has to be consistent with a search result as defined above.
7067 FixedArray* GetLiteralsFromOptimizedCodeMap(int index);
7068
7069 Code* GetCodeFromOptimizedCodeMap(int index);
7070
7071 // Clear optimized code map.
7072 void ClearOptimizedCodeMap();
7073
7074 // Removed a specific optimized code object from the optimized code map.
7075 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
7076
7077 void ClearTypeFeedbackInfo();
7078
7079 // Trims the optimized code map after entries have been removed.
7080 void TrimOptimizedCodeMap(int shrink_by);
7081
7082 // Add a new entry to the optimized code map.
7083 static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
7084 Handle<Context> native_context,
7085 Handle<Code> code,
7086 Handle<FixedArray> literals,
7087 BailoutId osr_ast_id);
7088
7089 // Layout description of the optimized code map.
7090 static const int kNextMapIndex = 0;
7091 static const int kEntriesStart = 1;
7092 static const int kContextOffset = 0;
7093 static const int kCachedCodeOffset = 1;
7094 static const int kLiteralsOffset = 2;
7095 static const int kOsrAstIdOffset = 3;
7096 static const int kEntryLength = 4;
7097 static const int kInitialLength = kEntriesStart + kEntryLength;
7098
7099 // [scope_info]: Scope info.
7100 DECL_ACCESSORS(scope_info, ScopeInfo)
7101
7102 // [construct stub]: Code stub for constructing instances of this function.
7103 DECL_ACCESSORS(construct_stub, Code)
7104
7105 // Returns if this function has been compiled to native code yet.
7106 inline bool is_compiled();
7107
7108 // [length]: The function length - usually the number of declared parameters.
7109 // Use up to 2^30 parameters.
7110 inline int length();
7111 inline void set_length(int value);
7112
7113 // [formal parameter count]: The declared number of parameters.
7114 inline int formal_parameter_count();
7115 inline void set_formal_parameter_count(int value);
7116
7117 // Set the formal parameter count so the function code will be
7118 // called without using argument adaptor frames.
7119 inline void DontAdaptArguments();
7120
7121 // [expected_nof_properties]: Expected number of properties for the function.
7122 inline int expected_nof_properties();
7123 inline void set_expected_nof_properties(int value);
7124
7125 // [feedback_vector] - accumulates ast node feedback from full-codegen and
7126 // (increasingly) from crankshafted code where sufficient feedback isn't
7127 // available. Currently the field is duplicated in
7128 // TypeFeedbackInfo::feedback_vector, but the allocation is done here.
7129 DECL_ACCESSORS(feedback_vector, FixedArray)
7130
7131 // [instance class name]: class name for instances.
7132 DECL_ACCESSORS(instance_class_name, Object)
7133
7134 // [function data]: This field holds some additional data for function.
7135 // Currently it either has FunctionTemplateInfo to make benefit the API
7136 // or Smi identifying a builtin function.
7137 // In the long run we don't want all functions to have this field but
7138 // we can fix that when we have a better model for storing hidden data
7139 // on objects.
7140 DECL_ACCESSORS(function_data, Object)
7141
7142 inline bool IsApiFunction();
7143 inline FunctionTemplateInfo* get_api_func_data();
7144 inline bool HasBuiltinFunctionId();
7145 inline BuiltinFunctionId builtin_function_id();
7146
7147 // [script info]: Script from which the function originates.
7148 DECL_ACCESSORS(script, Object)
7149
7150 // [num_literals]: Number of literals used by this function.
7151 inline int num_literals();
7152 inline void set_num_literals(int value);
7153
7154 // [start_position_and_type]: Field used to store both the source code
7155 // position, whether or not the function is a function expression,
7156 // and whether or not the function is a toplevel function. The two
7157 // least significants bit indicates whether the function is an
7158 // expression and the rest contains the source code position.
7159 inline int start_position_and_type();
7160 inline void set_start_position_and_type(int value);
7161
7162 // [debug info]: Debug information.
7163 DECL_ACCESSORS(debug_info, Object)
7164
7165 // [inferred name]: Name inferred from variable or property
7166 // assignment of this function. Used to facilitate debugging and
7167 // profiling of JavaScript code written in OO style, where almost
7168 // all functions are anonymous but are assigned to object
7169 // properties.
7170 DECL_ACCESSORS(inferred_name, String)
7171
7172 // The function's name if it is non-empty, otherwise the inferred name.
7173 String* DebugName();
7174
7175 // Position of the 'function' token in the script source.
7176 inline int function_token_position();
7177 inline void set_function_token_position(int function_token_position);
7178
7179 // Position of this function in the script source.
7180 inline int start_position();
7181 inline void set_start_position(int start_position);
7182
7183 // End position of this function in the script source.
7184 inline int end_position();
7185 inline void set_end_position(int end_position);
7186
7187 // Is this function a function expression in the source code.
7188 DECL_BOOLEAN_ACCESSORS(is_expression)
7189
7190 // Is this function a top-level function (scripts, evals).
7191 DECL_BOOLEAN_ACCESSORS(is_toplevel)
7192
7193 // Bit field containing various information collected by the compiler to
7194 // drive optimization.
7195 inline int compiler_hints();
7196 inline void set_compiler_hints(int value);
7197
7198 inline int ast_node_count();
7199 inline void set_ast_node_count(int count);
7200
7201 inline int profiler_ticks();
7202 inline void set_profiler_ticks(int ticks);
7203
7204 // Inline cache age is used to infer whether the function survived a context
7205 // disposal or not. In the former case we reset the opt_count.
7206 inline int ic_age();
7207 inline void set_ic_age(int age);
7208
7209 // Indicates if this function can be lazy compiled.
7210 // This is used to determine if we can safely flush code from a function
7211 // when doing GC if we expect that the function will no longer be used.
7212 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
7213
7214 // Indicates if this function can be lazy compiled without a context.
7215 // This is used to determine if we can force compilation without reaching
7216 // the function through program execution but through other means (e.g. heap
7217 // iteration by the debugger).
7218 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
7219
7220 // Indicates whether optimizations have been disabled for this
7221 // shared function info. If a function is repeatedly optimized or if
7222 // we cannot optimize the function we disable optimization to avoid
7223 // spending time attempting to optimize it again.
7224 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
7225
7226 // Indicates the language mode.
7227 inline StrictMode strict_mode();
7228 inline void set_strict_mode(StrictMode strict_mode);
7229
7230 // False if the function definitely does not allocate an arguments object.
7231 DECL_BOOLEAN_ACCESSORS(uses_arguments)
7232
7233 // True if the function has any duplicated parameter names.
7234 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
7235
7236 // Indicates whether the function is a native function.
7237 // These needs special treatment in .call and .apply since
7238 // null passed as the receiver should not be translated to the
7239 // global object.
7240 DECL_BOOLEAN_ACCESSORS(native)
7241
7242 // Indicate that this builtin needs to be inlined in crankshaft.
7243 DECL_BOOLEAN_ACCESSORS(inline_builtin)
7244
7245 // Indicates that the function was created by the Function function.
7246 // Though it's anonymous, toString should treat it as if it had the name
7247 // "anonymous". We don't set the name itself so that the system does not
7248 // see a binding for it.
7249 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
7250
7251 // Indicates whether the function is a bound function created using
7252 // the bind function.
7253 DECL_BOOLEAN_ACCESSORS(bound)
7254
7255 // Indicates that the function is anonymous (the name field can be set
7256 // through the API, which does not change this flag).
7257 DECL_BOOLEAN_ACCESSORS(is_anonymous)
7258
7259 // Is this a function or top-level/eval code.
7260 DECL_BOOLEAN_ACCESSORS(is_function)
7261
7262 // Indicates that the function cannot be optimized.
7263 DECL_BOOLEAN_ACCESSORS(dont_optimize)
7264
7265 // Indicates that the function cannot be inlined.
7266 DECL_BOOLEAN_ACCESSORS(dont_inline)
7267
7268 // Indicates that code for this function cannot be cached.
7269 DECL_BOOLEAN_ACCESSORS(dont_cache)
7270
7271 // Indicates that code for this function cannot be flushed.
7272 DECL_BOOLEAN_ACCESSORS(dont_flush)
7273
7274 // Indicates that this function is a generator.
7275 DECL_BOOLEAN_ACCESSORS(is_generator)
7276
7277 // Indicates whether or not the code in the shared function support
7278 // deoptimization.
7279 inline bool has_deoptimization_support();
7280
7281 // Enable deoptimization support through recompiled code.
7282 void EnableDeoptimizationSupport(Code* recompiled);
7283
7284 // Disable (further) attempted optimization of all functions sharing this
7285 // shared function info.
7286 void DisableOptimization(BailoutReason reason);
7287
7288 inline BailoutReason DisableOptimizationReason();
7289
7290 // Lookup the bailout ID and ASSERT that it exists in the non-optimized
7291 // code, returns whether it asserted (i.e., always true if assertions are
7292 // disabled).
7293 bool VerifyBailoutId(BailoutId id);
7294
7295 // [source code]: Source code for the function.
7296 bool HasSourceCode();
7297 Handle<Object> GetSourceCode();
7298
7299 // Number of times the function was optimized.
7300 inline int opt_count();
7301 inline void set_opt_count(int opt_count);
7302
7303 // Number of times the function was deoptimized.
7304 inline void set_deopt_count(int value);
7305 inline int deopt_count();
7306 inline void increment_deopt_count();
7307
7308 // Number of time we tried to re-enable optimization after it
7309 // was disabled due to high number of deoptimizations.
7310 inline void set_opt_reenable_tries(int value);
7311 inline int opt_reenable_tries();
7312
7313 inline void TryReenableOptimization();
7314
7315 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
7316 inline void set_counters(int value);
7317 inline int counters();
7318
7319 // Stores opt_count and bailout_reason as bit-fields.
7320 inline void set_opt_count_and_bailout_reason(int value);
7321 inline int opt_count_and_bailout_reason();
7322
set_bailout_reason(BailoutReason reason)7323 void set_bailout_reason(BailoutReason reason) {
7324 set_opt_count_and_bailout_reason(
7325 DisabledOptimizationReasonBits::update(opt_count_and_bailout_reason(),
7326 reason));
7327 }
7328
set_dont_optimize_reason(BailoutReason reason)7329 void set_dont_optimize_reason(BailoutReason reason) {
7330 set_bailout_reason(reason);
7331 set_dont_optimize(reason != kNoReason);
7332 }
7333
7334 // Check whether or not this function is inlineable.
7335 bool IsInlineable();
7336
7337 // Source size of this function.
7338 int SourceSize();
7339
7340 // Calculate the instance size.
7341 int CalculateInstanceSize();
7342
7343 // Calculate the number of in-object properties.
7344 int CalculateInObjectProperties();
7345
7346 // Dispatched behavior.
7347 // Set max_length to -1 for unlimited length.
7348 void SourceCodePrint(StringStream* accumulator, int max_length);
7349 DECLARE_PRINTER(SharedFunctionInfo)
7350 DECLARE_VERIFIER(SharedFunctionInfo)
7351
7352 void ResetForNewContext(int new_ic_age);
7353
7354 // Casting.
7355 static inline SharedFunctionInfo* cast(Object* obj);
7356
7357 // Constants.
7358 static const int kDontAdaptArgumentsSentinel = -1;
7359
7360 // Layout description.
7361 // Pointer fields.
7362 static const int kNameOffset = HeapObject::kHeaderSize;
7363 static const int kCodeOffset = kNameOffset + kPointerSize;
7364 static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
7365 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
7366 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
7367 static const int kInstanceClassNameOffset =
7368 kConstructStubOffset + kPointerSize;
7369 static const int kFunctionDataOffset =
7370 kInstanceClassNameOffset + kPointerSize;
7371 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
7372 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
7373 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
7374 static const int kFeedbackVectorOffset =
7375 kInferredNameOffset + kPointerSize;
7376 #if V8_HOST_ARCH_32_BIT
7377 // Smi fields.
7378 static const int kLengthOffset =
7379 kFeedbackVectorOffset + kPointerSize;
7380 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
7381 static const int kExpectedNofPropertiesOffset =
7382 kFormalParameterCountOffset + kPointerSize;
7383 static const int kNumLiteralsOffset =
7384 kExpectedNofPropertiesOffset + kPointerSize;
7385 static const int kStartPositionAndTypeOffset =
7386 kNumLiteralsOffset + kPointerSize;
7387 static const int kEndPositionOffset =
7388 kStartPositionAndTypeOffset + kPointerSize;
7389 static const int kFunctionTokenPositionOffset =
7390 kEndPositionOffset + kPointerSize;
7391 static const int kCompilerHintsOffset =
7392 kFunctionTokenPositionOffset + kPointerSize;
7393 static const int kOptCountAndBailoutReasonOffset =
7394 kCompilerHintsOffset + kPointerSize;
7395 static const int kCountersOffset =
7396 kOptCountAndBailoutReasonOffset + kPointerSize;
7397 static const int kAstNodeCountOffset =
7398 kCountersOffset + kPointerSize;
7399 static const int kProfilerTicksOffset =
7400 kAstNodeCountOffset + kPointerSize;
7401
7402 // Total size.
7403 static const int kSize = kProfilerTicksOffset + kPointerSize;
7404 #else
7405 // The only reason to use smi fields instead of int fields
7406 // is to allow iteration without maps decoding during
7407 // garbage collections.
7408 // To avoid wasting space on 64-bit architectures we use
7409 // the following trick: we group integer fields into pairs
7410 // First integer in each pair is shifted left by 1.
7411 // By doing this we guarantee that LSB of each kPointerSize aligned
7412 // word is not set and thus this word cannot be treated as pointer
7413 // to HeapObject during old space traversal.
7414 static const int kLengthOffset =
7415 kFeedbackVectorOffset + kPointerSize;
7416 static const int kFormalParameterCountOffset =
7417 kLengthOffset + kIntSize;
7418
7419 static const int kExpectedNofPropertiesOffset =
7420 kFormalParameterCountOffset + kIntSize;
7421 static const int kNumLiteralsOffset =
7422 kExpectedNofPropertiesOffset + kIntSize;
7423
7424 static const int kEndPositionOffset =
7425 kNumLiteralsOffset + kIntSize;
7426 static const int kStartPositionAndTypeOffset =
7427 kEndPositionOffset + kIntSize;
7428
7429 static const int kFunctionTokenPositionOffset =
7430 kStartPositionAndTypeOffset + kIntSize;
7431 static const int kCompilerHintsOffset =
7432 kFunctionTokenPositionOffset + kIntSize;
7433
7434 static const int kOptCountAndBailoutReasonOffset =
7435 kCompilerHintsOffset + kIntSize;
7436 static const int kCountersOffset =
7437 kOptCountAndBailoutReasonOffset + kIntSize;
7438
7439 static const int kAstNodeCountOffset =
7440 kCountersOffset + kIntSize;
7441 static const int kProfilerTicksOffset =
7442 kAstNodeCountOffset + kIntSize;
7443
7444 // Total size.
7445 static const int kSize = kProfilerTicksOffset + kIntSize;
7446
7447 #endif
7448
7449 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
7450
7451 typedef FixedBodyDescriptor<kNameOffset,
7452 kFeedbackVectorOffset + kPointerSize,
7453 kSize> BodyDescriptor;
7454
7455 // Bit positions in start_position_and_type.
7456 // The source code start position is in the 30 most significant bits of
7457 // the start_position_and_type field.
7458 static const int kIsExpressionBit = 0;
7459 static const int kIsTopLevelBit = 1;
7460 static const int kStartPositionShift = 2;
7461 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
7462
7463 // Bit positions in compiler_hints.
7464 enum CompilerHints {
7465 kAllowLazyCompilation,
7466 kAllowLazyCompilationWithoutContext,
7467 kOptimizationDisabled,
7468 kStrictModeFunction,
7469 kUsesArguments,
7470 kHasDuplicateParameters,
7471 kNative,
7472 kInlineBuiltin,
7473 kBoundFunction,
7474 kIsAnonymous,
7475 kNameShouldPrintAsAnonymous,
7476 kIsFunction,
7477 kDontOptimize,
7478 kDontInline,
7479 kDontCache,
7480 kDontFlush,
7481 kIsGenerator,
7482 kCompilerHintsCount // Pseudo entry
7483 };
7484
7485 class DeoptCountBits: public BitField<int, 0, 4> {};
7486 class OptReenableTriesBits: public BitField<int, 4, 18> {};
7487 class ICAgeBits: public BitField<int, 22, 8> {};
7488
7489 class OptCountBits: public BitField<int, 0, 22> {};
7490 class DisabledOptimizationReasonBits: public BitField<int, 22, 8> {};
7491
7492 private:
7493 #if V8_HOST_ARCH_32_BIT
7494 // On 32 bit platforms, compiler hints is a smi.
7495 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7496 static const int kCompilerHintsSize = kPointerSize;
7497 #else
7498 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7499 static const int kCompilerHintsSmiTagSize = 0;
7500 static const int kCompilerHintsSize = kIntSize;
7501 #endif
7502
7503 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7504 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7505
7506 public:
7507 // Constants for optimizing codegen for strict mode function and
7508 // native tests.
7509 // Allows to use byte-width instructions.
7510 static const int kStrictModeBitWithinByte =
7511 (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
7512
7513 static const int kNativeBitWithinByte =
7514 (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
7515
7516 #if defined(V8_TARGET_LITTLE_ENDIAN)
7517 static const int kStrictModeByteOffset = kCompilerHintsOffset +
7518 (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
7519 static const int kNativeByteOffset = kCompilerHintsOffset +
7520 (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
7521 #elif defined(V8_TARGET_BIG_ENDIAN)
7522 static const int kStrictModeByteOffset = kCompilerHintsOffset +
7523 (kCompilerHintsSize - 1) -
7524 ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
7525 static const int kNativeByteOffset = kCompilerHintsOffset +
7526 (kCompilerHintsSize - 1) -
7527 ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
7528 #else
7529 #error Unknown byte ordering
7530 #endif
7531
7532 private:
7533 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7534 };
7535
7536
7537 class JSGeneratorObject: public JSObject {
7538 public:
7539 // [function]: The function corresponding to this generator object.
7540 DECL_ACCESSORS(function, JSFunction)
7541
7542 // [context]: The context of the suspended computation.
7543 DECL_ACCESSORS(context, Context)
7544
7545 // [receiver]: The receiver of the suspended computation.
7546 DECL_ACCESSORS(receiver, Object)
7547
7548 // [continuation]: Offset into code of continuation.
7549 //
7550 // A positive offset indicates a suspended generator. The special
7551 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7552 // cannot be resumed.
7553 inline int continuation();
7554 inline void set_continuation(int continuation);
7555 inline bool is_closed();
7556 inline bool is_executing();
7557 inline bool is_suspended();
7558
7559 // [operand_stack]: Saved operand stack.
7560 DECL_ACCESSORS(operand_stack, FixedArray)
7561
7562 // [stack_handler_index]: Index of first stack handler in operand_stack, or -1
7563 // if the captured activation had no stack handler.
7564 inline int stack_handler_index();
7565 inline void set_stack_handler_index(int stack_handler_index);
7566
7567 // Casting.
7568 static inline JSGeneratorObject* cast(Object* obj);
7569
7570 // Dispatched behavior.
7571 DECLARE_PRINTER(JSGeneratorObject)
7572 DECLARE_VERIFIER(JSGeneratorObject)
7573
7574 // Magic sentinel values for the continuation.
7575 static const int kGeneratorExecuting = -1;
7576 static const int kGeneratorClosed = 0;
7577
7578 // Layout description.
7579 static const int kFunctionOffset = JSObject::kHeaderSize;
7580 static const int kContextOffset = kFunctionOffset + kPointerSize;
7581 static const int kReceiverOffset = kContextOffset + kPointerSize;
7582 static const int kContinuationOffset = kReceiverOffset + kPointerSize;
7583 static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
7584 static const int kStackHandlerIndexOffset =
7585 kOperandStackOffset + kPointerSize;
7586 static const int kSize = kStackHandlerIndexOffset + kPointerSize;
7587
7588 // Resume mode, for use by runtime functions.
7589 enum ResumeMode { NEXT, THROW };
7590
7591 // Yielding from a generator returns an object with the following inobject
7592 // properties. See Context::iterator_result_map() for the map.
7593 static const int kResultValuePropertyIndex = 0;
7594 static const int kResultDonePropertyIndex = 1;
7595 static const int kResultPropertyCount = 2;
7596
7597 static const int kResultValuePropertyOffset = JSObject::kHeaderSize;
7598 static const int kResultDonePropertyOffset =
7599 kResultValuePropertyOffset + kPointerSize;
7600 static const int kResultSize = kResultDonePropertyOffset + kPointerSize;
7601
7602 private:
7603 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7604 };
7605
7606
7607 // Representation for module instance objects.
7608 class JSModule: public JSObject {
7609 public:
7610 // [context]: the context holding the module's locals, or undefined if none.
7611 DECL_ACCESSORS(context, Object)
7612
7613 // [scope_info]: Scope info.
7614 DECL_ACCESSORS(scope_info, ScopeInfo)
7615
7616 // Casting.
7617 static inline JSModule* cast(Object* obj);
7618
7619 // Dispatched behavior.
7620 DECLARE_PRINTER(JSModule)
7621 DECLARE_VERIFIER(JSModule)
7622
7623 // Layout description.
7624 static const int kContextOffset = JSObject::kHeaderSize;
7625 static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7626 static const int kSize = kScopeInfoOffset + kPointerSize;
7627
7628 private:
7629 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7630 };
7631
7632
7633 // JSFunction describes JavaScript functions.
7634 class JSFunction: public JSObject {
7635 public:
7636 // [prototype_or_initial_map]:
7637 DECL_ACCESSORS(prototype_or_initial_map, Object)
7638
7639 // [shared]: The information about the function that
7640 // can be shared by instances.
7641 DECL_ACCESSORS(shared, SharedFunctionInfo)
7642
7643 // [context]: The context for this function.
7644 inline Context* context();
7645 inline void set_context(Object* context);
7646
7647 // [code]: The generated code object for this function. Executed
7648 // when the function is invoked, e.g. foo() or new foo(). See
7649 // [[Call]] and [[Construct]] description in ECMA-262, section
7650 // 8.6.2, page 27.
7651 inline Code* code();
7652 inline void set_code(Code* code);
7653 inline void set_code_no_write_barrier(Code* code);
7654 inline void ReplaceCode(Code* code);
7655
7656 // Tells whether this function is builtin.
7657 inline bool IsBuiltin();
7658
7659 // Tells whether this function is defined in a native script.
7660 inline bool IsNative();
7661
7662 // Tells whether or not the function needs arguments adaption.
7663 inline bool NeedsArgumentsAdaption();
7664
7665 // Tells whether or not this function has been optimized.
7666 inline bool IsOptimized();
7667
7668 // Tells whether or not this function can be optimized.
7669 inline bool IsOptimizable();
7670
7671 // Mark this function for lazy recompilation. The function will be
7672 // recompiled the next time it is executed.
7673 void MarkForOptimization();
7674 void MarkForConcurrentOptimization();
7675 void MarkInOptimizationQueue();
7676
7677 // Tells whether or not the function is already marked for lazy
7678 // recompilation.
7679 inline bool IsMarkedForOptimization();
7680 inline bool IsMarkedForConcurrentOptimization();
7681
7682 // Tells whether or not the function is on the concurrent recompilation queue.
7683 inline bool IsInOptimizationQueue();
7684
7685 // Inobject slack tracking is the way to reclaim unused inobject space.
7686 //
7687 // The instance size is initially determined by adding some slack to
7688 // expected_nof_properties (to allow for a few extra properties added
7689 // after the constructor). There is no guarantee that the extra space
7690 // will not be wasted.
7691 //
7692 // Here is the algorithm to reclaim the unused inobject space:
7693 // - Detect the first constructor call for this JSFunction.
7694 // When it happens enter the "in progress" state: initialize construction
7695 // counter in the initial_map and set the |done_inobject_slack_tracking|
7696 // flag.
7697 // - While the tracking is in progress create objects filled with
7698 // one_pointer_filler_map instead of undefined_value. This way they can be
7699 // resized quickly and safely.
7700 // - Once enough (kGenerousAllocationCount) objects have been created
7701 // compute the 'slack' (traverse the map transition tree starting from the
7702 // initial_map and find the lowest value of unused_property_fields).
7703 // - Traverse the transition tree again and decrease the instance size
7704 // of every map. Existing objects will resize automatically (they are
7705 // filled with one_pointer_filler_map). All further allocations will
7706 // use the adjusted instance size.
7707 // - SharedFunctionInfo's expected_nof_properties left unmodified since
7708 // allocations made using different closures could actually create different
7709 // kind of objects (see prototype inheritance pattern).
7710 //
7711 // Important: inobject slack tracking is not attempted during the snapshot
7712 // creation.
7713
7714 static const int kGenerousAllocationCount = Map::ConstructionCount::kMax;
7715 static const int kFinishSlackTracking = 1;
7716 static const int kNoSlackTracking = 0;
7717
7718 // True if the initial_map is set and the object constructions countdown
7719 // counter is not zero.
7720 inline bool IsInobjectSlackTrackingInProgress();
7721
7722 // Starts the tracking.
7723 // Initializes object constructions countdown counter in the initial map.
7724 // IsInobjectSlackTrackingInProgress is normally true after this call,
7725 // except when tracking have not been started (e.g. the map has no unused
7726 // properties or the snapshot is being built).
7727 void StartInobjectSlackTracking();
7728
7729 // Completes the tracking.
7730 // IsInobjectSlackTrackingInProgress is false after this call.
7731 void CompleteInobjectSlackTracking();
7732
7733 // [literals_or_bindings]: Fixed array holding either
7734 // the materialized literals or the bindings of a bound function.
7735 //
7736 // If the function contains object, regexp or array literals, the
7737 // literals array prefix contains the object, regexp, and array
7738 // function to be used when creating these literals. This is
7739 // necessary so that we do not dynamically lookup the object, regexp
7740 // or array functions. Performing a dynamic lookup, we might end up
7741 // using the functions from a new context that we should not have
7742 // access to.
7743 //
7744 // On bound functions, the array is a (copy-on-write) fixed-array containing
7745 // the function that was bound, bound this-value and any bound
7746 // arguments. Bound functions never contain literals.
7747 DECL_ACCESSORS(literals_or_bindings, FixedArray)
7748
7749 inline FixedArray* literals();
7750 inline void set_literals(FixedArray* literals);
7751
7752 inline FixedArray* function_bindings();
7753 inline void set_function_bindings(FixedArray* bindings);
7754
7755 // The initial map for an object created by this constructor.
7756 inline Map* initial_map();
7757 inline void set_initial_map(Map* value);
7758 inline bool has_initial_map();
7759 static void EnsureHasInitialMap(Handle<JSFunction> function);
7760
7761 // Get and set the prototype property on a JSFunction. If the
7762 // function has an initial map the prototype is set on the initial
7763 // map. Otherwise, the prototype is put in the initial map field
7764 // until an initial map is needed.
7765 inline bool has_prototype();
7766 inline bool has_instance_prototype();
7767 inline Object* prototype();
7768 inline Object* instance_prototype();
7769 static void SetPrototype(Handle<JSFunction> function,
7770 Handle<Object> value);
7771 static void SetInstancePrototype(Handle<JSFunction> function,
7772 Handle<Object> value);
7773
7774 // After prototype is removed, it will not be created when accessed, and
7775 // [[Construct]] from this function will not be allowed.
7776 bool RemovePrototype();
7777 inline bool should_have_prototype();
7778
7779 // Accessor for this function's initial map's [[class]]
7780 // property. This is primarily used by ECMA native functions. This
7781 // method sets the class_name field of this function's initial map
7782 // to a given value. It creates an initial map if this function does
7783 // not have one. Note that this method does not copy the initial map
7784 // if it has one already, but simply replaces it with the new value.
7785 // Instances created afterwards will have a map whose [[class]] is
7786 // set to 'value', but there is no guarantees on instances created
7787 // before.
7788 void SetInstanceClassName(String* name);
7789
7790 // Returns if this function has been compiled to native code yet.
7791 inline bool is_compiled();
7792
7793 // [next_function_link]: Links functions into various lists, e.g. the list
7794 // of optimized functions hanging off the native_context. The CodeFlusher
7795 // uses this link to chain together flushing candidates. Treated weakly
7796 // by the garbage collector.
7797 DECL_ACCESSORS(next_function_link, Object)
7798
7799 // Prints the name of the function using PrintF.
7800 void PrintName(FILE* out = stdout);
7801
7802 // Casting.
7803 static inline JSFunction* cast(Object* obj);
7804
7805 // Iterates the objects, including code objects indirectly referenced
7806 // through pointers to the first instruction in the code object.
7807 void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
7808
7809 // Dispatched behavior.
7810 DECLARE_PRINTER(JSFunction)
7811 DECLARE_VERIFIER(JSFunction)
7812
7813 // Returns the number of allocated literals.
7814 inline int NumberOfLiterals();
7815
7816 // Retrieve the native context from a function's literal array.
7817 static Context* NativeContextFromLiterals(FixedArray* literals);
7818
7819 // Used for flags such as --hydrogen-filter.
7820 bool PassesFilter(const char* raw_filter);
7821
7822 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7823 // kSize) is weak and has special handling during garbage collection.
7824 static const int kCodeEntryOffset = JSObject::kHeaderSize;
7825 static const int kPrototypeOrInitialMapOffset =
7826 kCodeEntryOffset + kPointerSize;
7827 static const int kSharedFunctionInfoOffset =
7828 kPrototypeOrInitialMapOffset + kPointerSize;
7829 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7830 static const int kLiteralsOffset = kContextOffset + kPointerSize;
7831 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
7832 static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
7833 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
7834
7835 // Layout of the literals array.
7836 static const int kLiteralsPrefixSize = 1;
7837 static const int kLiteralNativeContextIndex = 0;
7838
7839 // Layout of the bound-function binding array.
7840 static const int kBoundFunctionIndex = 0;
7841 static const int kBoundThisIndex = 1;
7842 static const int kBoundArgumentsStartIndex = 2;
7843
7844 private:
7845 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7846 };
7847
7848
7849 // JSGlobalProxy's prototype must be a JSGlobalObject or null,
7850 // and the prototype is hidden. JSGlobalProxy always delegates
7851 // property accesses to its prototype if the prototype is not null.
7852 //
7853 // A JSGlobalProxy can be reinitialized which will preserve its identity.
7854 //
7855 // Accessing a JSGlobalProxy requires security check.
7856
7857 class JSGlobalProxy : public JSObject {
7858 public:
7859 // [native_context]: the owner native context of this global proxy object.
7860 // It is null value if this object is not used by any context.
7861 DECL_ACCESSORS(native_context, Object)
7862
7863 // [hash]: The hash code property (undefined if not initialized yet).
7864 DECL_ACCESSORS(hash, Object)
7865
7866 // Casting.
7867 static inline JSGlobalProxy* cast(Object* obj);
7868
7869 inline bool IsDetachedFrom(GlobalObject* global);
7870
7871 // Dispatched behavior.
7872 DECLARE_PRINTER(JSGlobalProxy)
7873 DECLARE_VERIFIER(JSGlobalProxy)
7874
7875 // Layout description.
7876 static const int kNativeContextOffset = JSObject::kHeaderSize;
7877 static const int kHashOffset = kNativeContextOffset + kPointerSize;
7878 static const int kSize = kHashOffset + kPointerSize;
7879
7880 private:
7881 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7882 };
7883
7884
7885 // Forward declaration.
7886 class JSBuiltinsObject;
7887
7888 // Common super class for JavaScript global objects and the special
7889 // builtins global objects.
7890 class GlobalObject: public JSObject {
7891 public:
7892 // [builtins]: the object holding the runtime routines written in JS.
7893 DECL_ACCESSORS(builtins, JSBuiltinsObject)
7894
7895 // [native context]: the natives corresponding to this global object.
7896 DECL_ACCESSORS(native_context, Context)
7897
7898 // [global context]: the most recent (i.e. innermost) global context.
7899 DECL_ACCESSORS(global_context, Context)
7900
7901 // [global receiver]: the global receiver object of the context
7902 DECL_ACCESSORS(global_receiver, JSObject)
7903
7904 // Retrieve the property cell used to store a property.
7905 PropertyCell* GetPropertyCell(LookupResult* result);
7906
7907 // Casting.
7908 static inline GlobalObject* cast(Object* obj);
7909
7910 // Layout description.
7911 static const int kBuiltinsOffset = JSObject::kHeaderSize;
7912 static const int kNativeContextOffset = kBuiltinsOffset + kPointerSize;
7913 static const int kGlobalContextOffset = kNativeContextOffset + kPointerSize;
7914 static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize;
7915 static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
7916
7917 private:
7918 DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
7919 };
7920
7921
7922 // JavaScript global object.
7923 class JSGlobalObject: public GlobalObject {
7924 public:
7925 // Casting.
7926 static inline JSGlobalObject* cast(Object* obj);
7927
7928 // Ensure that the global object has a cell for the given property name.
7929 static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
7930 Handle<Name> name);
7931
7932 inline bool IsDetached();
7933
7934 // Dispatched behavior.
7935 DECLARE_PRINTER(JSGlobalObject)
7936 DECLARE_VERIFIER(JSGlobalObject)
7937
7938 // Layout description.
7939 static const int kSize = GlobalObject::kHeaderSize;
7940
7941 private:
7942 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7943 };
7944
7945
7946 // Builtins global object which holds the runtime routines written in
7947 // JavaScript.
7948 class JSBuiltinsObject: public GlobalObject {
7949 public:
7950 // Accessors for the runtime routines written in JavaScript.
7951 inline Object* javascript_builtin(Builtins::JavaScript id);
7952 inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
7953
7954 // Accessors for code of the runtime routines written in JavaScript.
7955 inline Code* javascript_builtin_code(Builtins::JavaScript id);
7956 inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
7957
7958 // Casting.
7959 static inline JSBuiltinsObject* cast(Object* obj);
7960
7961 // Dispatched behavior.
7962 DECLARE_PRINTER(JSBuiltinsObject)
7963 DECLARE_VERIFIER(JSBuiltinsObject)
7964
7965 // Layout description. The size of the builtins object includes
7966 // room for two pointers per runtime routine written in javascript
7967 // (function and code object).
7968 static const int kJSBuiltinsCount = Builtins::id_count;
7969 static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
7970 static const int kJSBuiltinsCodeOffset =
7971 GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
7972 static const int kSize =
7973 kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
7974
OffsetOfFunctionWithId(Builtins::JavaScript id)7975 static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
7976 return kJSBuiltinsOffset + id * kPointerSize;
7977 }
7978
OffsetOfCodeWithId(Builtins::JavaScript id)7979 static int OffsetOfCodeWithId(Builtins::JavaScript id) {
7980 return kJSBuiltinsCodeOffset + id * kPointerSize;
7981 }
7982
7983 private:
7984 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
7985 };
7986
7987
7988 // Representation for JS Wrapper objects, String, Number, Boolean, etc.
7989 class JSValue: public JSObject {
7990 public:
7991 // [value]: the object being wrapped.
7992 DECL_ACCESSORS(value, Object)
7993
7994 // Casting.
7995 static inline JSValue* cast(Object* obj);
7996
7997 // Dispatched behavior.
7998 DECLARE_PRINTER(JSValue)
7999 DECLARE_VERIFIER(JSValue)
8000
8001 // Layout description.
8002 static const int kValueOffset = JSObject::kHeaderSize;
8003 static const int kSize = kValueOffset + kPointerSize;
8004
8005 private:
8006 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
8007 };
8008
8009
8010 class DateCache;
8011
8012 // Representation for JS date objects.
8013 class JSDate: public JSObject {
8014 public:
8015 // If one component is NaN, all of them are, indicating a NaN time value.
8016 // [value]: the time value.
8017 DECL_ACCESSORS(value, Object)
8018 // [year]: caches year. Either undefined, smi, or NaN.
8019 DECL_ACCESSORS(year, Object)
8020 // [month]: caches month. Either undefined, smi, or NaN.
8021 DECL_ACCESSORS(month, Object)
8022 // [day]: caches day. Either undefined, smi, or NaN.
8023 DECL_ACCESSORS(day, Object)
8024 // [weekday]: caches day of week. Either undefined, smi, or NaN.
8025 DECL_ACCESSORS(weekday, Object)
8026 // [hour]: caches hours. Either undefined, smi, or NaN.
8027 DECL_ACCESSORS(hour, Object)
8028 // [min]: caches minutes. Either undefined, smi, or NaN.
8029 DECL_ACCESSORS(min, Object)
8030 // [sec]: caches seconds. Either undefined, smi, or NaN.
8031 DECL_ACCESSORS(sec, Object)
8032 // [cache stamp]: sample of the date cache stamp at the
8033 // moment when chached fields were cached.
8034 DECL_ACCESSORS(cache_stamp, Object)
8035
8036 // Casting.
8037 static inline JSDate* cast(Object* obj);
8038
8039 // Returns the date field with the specified index.
8040 // See FieldIndex for the list of date fields.
8041 static Object* GetField(Object* date, Smi* index);
8042
8043 void SetValue(Object* value, bool is_value_nan);
8044
8045
8046 // Dispatched behavior.
8047 DECLARE_PRINTER(JSDate)
8048 DECLARE_VERIFIER(JSDate)
8049
8050 // The order is important. It must be kept in sync with date macros
8051 // in macros.py.
8052 enum FieldIndex {
8053 kDateValue,
8054 kYear,
8055 kMonth,
8056 kDay,
8057 kWeekday,
8058 kHour,
8059 kMinute,
8060 kSecond,
8061 kFirstUncachedField,
8062 kMillisecond = kFirstUncachedField,
8063 kDays,
8064 kTimeInDay,
8065 kFirstUTCField,
8066 kYearUTC = kFirstUTCField,
8067 kMonthUTC,
8068 kDayUTC,
8069 kWeekdayUTC,
8070 kHourUTC,
8071 kMinuteUTC,
8072 kSecondUTC,
8073 kMillisecondUTC,
8074 kDaysUTC,
8075 kTimeInDayUTC,
8076 kTimezoneOffset
8077 };
8078
8079 // Layout description.
8080 static const int kValueOffset = JSObject::kHeaderSize;
8081 static const int kYearOffset = kValueOffset + kPointerSize;
8082 static const int kMonthOffset = kYearOffset + kPointerSize;
8083 static const int kDayOffset = kMonthOffset + kPointerSize;
8084 static const int kWeekdayOffset = kDayOffset + kPointerSize;
8085 static const int kHourOffset = kWeekdayOffset + kPointerSize;
8086 static const int kMinOffset = kHourOffset + kPointerSize;
8087 static const int kSecOffset = kMinOffset + kPointerSize;
8088 static const int kCacheStampOffset = kSecOffset + kPointerSize;
8089 static const int kSize = kCacheStampOffset + kPointerSize;
8090
8091 private:
8092 inline Object* DoGetField(FieldIndex index);
8093
8094 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
8095
8096 // Computes and caches the cacheable fields of the date.
8097 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
8098
8099
8100 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
8101 };
8102
8103
8104 // Representation of message objects used for error reporting through
8105 // the API. The messages are formatted in JavaScript so this object is
8106 // a real JavaScript object. The information used for formatting the
8107 // error messages are not directly accessible from JavaScript to
8108 // prevent leaking information to user code called during error
8109 // formatting.
8110 class JSMessageObject: public JSObject {
8111 public:
8112 // [type]: the type of error message.
8113 DECL_ACCESSORS(type, String)
8114
8115 // [arguments]: the arguments for formatting the error message.
8116 DECL_ACCESSORS(arguments, JSArray)
8117
8118 // [script]: the script from which the error message originated.
8119 DECL_ACCESSORS(script, Object)
8120
8121 // [stack_frames]: an array of stack frames for this error object.
8122 DECL_ACCESSORS(stack_frames, Object)
8123
8124 // [start_position]: the start position in the script for the error message.
8125 inline int start_position();
8126 inline void set_start_position(int value);
8127
8128 // [end_position]: the end position in the script for the error message.
8129 inline int end_position();
8130 inline void set_end_position(int value);
8131
8132 // Casting.
8133 static inline JSMessageObject* cast(Object* obj);
8134
8135 // Dispatched behavior.
8136 DECLARE_PRINTER(JSMessageObject)
8137 DECLARE_VERIFIER(JSMessageObject)
8138
8139 // Layout description.
8140 static const int kTypeOffset = JSObject::kHeaderSize;
8141 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
8142 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
8143 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
8144 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
8145 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
8146 static const int kSize = kEndPositionOffset + kPointerSize;
8147
8148 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
8149 kStackFramesOffset + kPointerSize,
8150 kSize> BodyDescriptor;
8151 };
8152
8153
8154 // Regular expressions
8155 // The regular expression holds a single reference to a FixedArray in
8156 // the kDataOffset field.
8157 // The FixedArray contains the following data:
8158 // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
8159 // - reference to the original source string
8160 // - reference to the original flag string
8161 // If it is an atom regexp
8162 // - a reference to a literal string to search for
8163 // If it is an irregexp regexp:
8164 // - a reference to code for ASCII inputs (bytecode or compiled), or a smi
8165 // used for tracking the last usage (used for code flushing).
8166 // - a reference to code for UC16 inputs (bytecode or compiled), or a smi
8167 // used for tracking the last usage (used for code flushing)..
8168 // - max number of registers used by irregexp implementations.
8169 // - number of capture registers (output values) of the regexp.
8170 class JSRegExp: public JSObject {
8171 public:
8172 // Meaning of Type:
8173 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
8174 // ATOM: A simple string to match against using an indexOf operation.
8175 // IRREGEXP: Compiled with Irregexp.
8176 // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
8177 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
8178 enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 };
8179
8180 class Flags {
8181 public:
Flags(uint32_t value)8182 explicit Flags(uint32_t value) : value_(value) { }
is_global()8183 bool is_global() { return (value_ & GLOBAL) != 0; }
is_ignore_case()8184 bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
is_multiline()8185 bool is_multiline() { return (value_ & MULTILINE) != 0; }
value()8186 uint32_t value() { return value_; }
8187 private:
8188 uint32_t value_;
8189 };
8190
8191 DECL_ACCESSORS(data, Object)
8192
8193 inline Type TypeTag();
8194 inline int CaptureCount();
8195 inline Flags GetFlags();
8196 inline String* Pattern();
8197 inline Object* DataAt(int index);
8198 // Set implementation data after the object has been prepared.
8199 inline void SetDataAt(int index, Object* value);
8200
code_index(bool is_ascii)8201 static int code_index(bool is_ascii) {
8202 if (is_ascii) {
8203 return kIrregexpASCIICodeIndex;
8204 } else {
8205 return kIrregexpUC16CodeIndex;
8206 }
8207 }
8208
saved_code_index(bool is_ascii)8209 static int saved_code_index(bool is_ascii) {
8210 if (is_ascii) {
8211 return kIrregexpASCIICodeSavedIndex;
8212 } else {
8213 return kIrregexpUC16CodeSavedIndex;
8214 }
8215 }
8216
8217 static inline JSRegExp* cast(Object* obj);
8218
8219 // Dispatched behavior.
8220 DECLARE_VERIFIER(JSRegExp)
8221
8222 static const int kDataOffset = JSObject::kHeaderSize;
8223 static const int kSize = kDataOffset + kPointerSize;
8224
8225 // Indices in the data array.
8226 static const int kTagIndex = 0;
8227 static const int kSourceIndex = kTagIndex + 1;
8228 static const int kFlagsIndex = kSourceIndex + 1;
8229 static const int kDataIndex = kFlagsIndex + 1;
8230 // The data fields are used in different ways depending on the
8231 // value of the tag.
8232 // Atom regexps (literal strings).
8233 static const int kAtomPatternIndex = kDataIndex;
8234
8235 static const int kAtomDataSize = kAtomPatternIndex + 1;
8236
8237 // Irregexp compiled code or bytecode for ASCII. If compilation
8238 // fails, this fields hold an exception object that should be
8239 // thrown if the regexp is used again.
8240 static const int kIrregexpASCIICodeIndex = kDataIndex;
8241 // Irregexp compiled code or bytecode for UC16. If compilation
8242 // fails, this fields hold an exception object that should be
8243 // thrown if the regexp is used again.
8244 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
8245
8246 // Saved instance of Irregexp compiled code or bytecode for ASCII that
8247 // is a potential candidate for flushing.
8248 static const int kIrregexpASCIICodeSavedIndex = kDataIndex + 2;
8249 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
8250 // a potential candidate for flushing.
8251 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
8252
8253 // Maximal number of registers used by either ASCII or UC16.
8254 // Only used to check that there is enough stack space
8255 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
8256 // Number of captures in the compiled regexp.
8257 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
8258
8259 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
8260
8261 // Offsets directly into the data fixed array.
8262 static const int kDataTagOffset =
8263 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
8264 static const int kDataAsciiCodeOffset =
8265 FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize;
8266 static const int kDataUC16CodeOffset =
8267 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
8268 static const int kIrregexpCaptureCountOffset =
8269 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
8270
8271 // In-object fields.
8272 static const int kSourceFieldIndex = 0;
8273 static const int kGlobalFieldIndex = 1;
8274 static const int kIgnoreCaseFieldIndex = 2;
8275 static const int kMultilineFieldIndex = 3;
8276 static const int kLastIndexFieldIndex = 4;
8277 static const int kInObjectFieldCount = 5;
8278
8279 // The uninitialized value for a regexp code object.
8280 static const int kUninitializedValue = -1;
8281
8282 // The compilation error value for the regexp code object. The real error
8283 // object is in the saved code field.
8284 static const int kCompilationErrorValue = -2;
8285
8286 // When we store the sweep generation at which we moved the code from the
8287 // code index to the saved code index we mask it of to be in the [0:255]
8288 // range.
8289 static const int kCodeAgeMask = 0xff;
8290 };
8291
8292
8293 class CompilationCacheShape : public BaseShape<HashTableKey*> {
8294 public:
IsMatch(HashTableKey * key,Object * value)8295 static inline bool IsMatch(HashTableKey* key, Object* value) {
8296 return key->IsMatch(value);
8297 }
8298
Hash(HashTableKey * key)8299 static inline uint32_t Hash(HashTableKey* key) {
8300 return key->Hash();
8301 }
8302
HashForObject(HashTableKey * key,Object * object)8303 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8304 return key->HashForObject(object);
8305 }
8306
8307 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8308
8309 static const int kPrefixSize = 0;
8310 static const int kEntrySize = 2;
8311 };
8312
8313
8314 class CompilationCacheTable: public HashTable<CompilationCacheTable,
8315 CompilationCacheShape,
8316 HashTableKey*> {
8317 public:
8318 // Find cached value for a string key, otherwise return null.
8319 Handle<Object> Lookup(Handle<String> src, Handle<Context> context);
8320 Handle<Object> LookupEval(Handle<String> src, Handle<Context> context,
8321 StrictMode strict_mode, int scope_position);
8322 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
8323 static Handle<CompilationCacheTable> Put(
8324 Handle<CompilationCacheTable> cache, Handle<String> src,
8325 Handle<Context> context, Handle<Object> value);
8326 static Handle<CompilationCacheTable> PutEval(
8327 Handle<CompilationCacheTable> cache, Handle<String> src,
8328 Handle<Context> context, Handle<SharedFunctionInfo> value,
8329 int scope_position);
8330 static Handle<CompilationCacheTable> PutRegExp(
8331 Handle<CompilationCacheTable> cache, Handle<String> src,
8332 JSRegExp::Flags flags, Handle<FixedArray> value);
8333 void Remove(Object* value);
8334
8335 static inline CompilationCacheTable* cast(Object* obj);
8336
8337 private:
8338 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
8339 };
8340
8341
8342 class CodeCache: public Struct {
8343 public:
8344 DECL_ACCESSORS(default_cache, FixedArray)
8345 DECL_ACCESSORS(normal_type_cache, Object)
8346
8347 // Add the code object to the cache.
8348 static void Update(
8349 Handle<CodeCache> cache, Handle<Name> name, Handle<Code> code);
8350
8351 // Lookup code object in the cache. Returns code object if found and undefined
8352 // if not.
8353 Object* Lookup(Name* name, Code::Flags flags);
8354
8355 // Get the internal index of a code object in the cache. Returns -1 if the
8356 // code object is not in that cache. This index can be used to later call
8357 // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
8358 // RemoveByIndex.
8359 int GetIndex(Object* name, Code* code);
8360
8361 // Remove an object from the cache with the provided internal index.
8362 void RemoveByIndex(Object* name, Code* code, int index);
8363
8364 static inline CodeCache* cast(Object* obj);
8365
8366 // Dispatched behavior.
8367 DECLARE_PRINTER(CodeCache)
8368 DECLARE_VERIFIER(CodeCache)
8369
8370 static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
8371 static const int kNormalTypeCacheOffset =
8372 kDefaultCacheOffset + kPointerSize;
8373 static const int kSize = kNormalTypeCacheOffset + kPointerSize;
8374
8375 private:
8376 static void UpdateDefaultCache(
8377 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
8378 static void UpdateNormalTypeCache(
8379 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
8380 Object* LookupDefaultCache(Name* name, Code::Flags flags);
8381 Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
8382
8383 // Code cache layout of the default cache. Elements are alternating name and
8384 // code objects for non normal load/store/call IC's.
8385 static const int kCodeCacheEntrySize = 2;
8386 static const int kCodeCacheEntryNameOffset = 0;
8387 static const int kCodeCacheEntryCodeOffset = 1;
8388
8389 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
8390 };
8391
8392
8393 class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
8394 public:
IsMatch(HashTableKey * key,Object * value)8395 static inline bool IsMatch(HashTableKey* key, Object* value) {
8396 return key->IsMatch(value);
8397 }
8398
Hash(HashTableKey * key)8399 static inline uint32_t Hash(HashTableKey* key) {
8400 return key->Hash();
8401 }
8402
HashForObject(HashTableKey * key,Object * object)8403 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8404 return key->HashForObject(object);
8405 }
8406
8407 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8408
8409 static const int kPrefixSize = 0;
8410 static const int kEntrySize = 2;
8411 };
8412
8413
8414 class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
8415 CodeCacheHashTableShape,
8416 HashTableKey*> {
8417 public:
8418 Object* Lookup(Name* name, Code::Flags flags);
8419 static Handle<CodeCacheHashTable> Put(
8420 Handle<CodeCacheHashTable> table,
8421 Handle<Name> name,
8422 Handle<Code> code);
8423
8424 int GetIndex(Name* name, Code::Flags flags);
8425 void RemoveByIndex(int index);
8426
8427 static inline CodeCacheHashTable* cast(Object* obj);
8428
8429 // Initial size of the fixed array backing the hash table.
8430 static const int kInitialSize = 64;
8431
8432 private:
8433 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8434 };
8435
8436
8437 class PolymorphicCodeCache: public Struct {
8438 public:
8439 DECL_ACCESSORS(cache, Object)
8440
8441 static void Update(Handle<PolymorphicCodeCache> cache,
8442 MapHandleList* maps,
8443 Code::Flags flags,
8444 Handle<Code> code);
8445
8446
8447 // Returns an undefined value if the entry is not found.
8448 Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
8449
8450 static inline PolymorphicCodeCache* cast(Object* obj);
8451
8452 // Dispatched behavior.
8453 DECLARE_PRINTER(PolymorphicCodeCache)
8454 DECLARE_VERIFIER(PolymorphicCodeCache)
8455
8456 static const int kCacheOffset = HeapObject::kHeaderSize;
8457 static const int kSize = kCacheOffset + kPointerSize;
8458
8459 private:
8460 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
8461 };
8462
8463
8464 class PolymorphicCodeCacheHashTable
8465 : public HashTable<PolymorphicCodeCacheHashTable,
8466 CodeCacheHashTableShape,
8467 HashTableKey*> {
8468 public:
8469 Object* Lookup(MapHandleList* maps, int code_kind);
8470
8471 static Handle<PolymorphicCodeCacheHashTable> Put(
8472 Handle<PolymorphicCodeCacheHashTable> hash_table,
8473 MapHandleList* maps,
8474 int code_kind,
8475 Handle<Code> code);
8476
8477 static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
8478
8479 static const int kInitialSize = 64;
8480 private:
8481 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
8482 };
8483
8484
8485 class TypeFeedbackInfo: public Struct {
8486 public:
8487 inline int ic_total_count();
8488 inline void set_ic_total_count(int count);
8489
8490 inline int ic_with_type_info_count();
8491 inline void change_ic_with_type_info_count(int count);
8492
8493 inline void initialize_storage();
8494
8495 inline void change_own_type_change_checksum();
8496 inline int own_type_change_checksum();
8497
8498 inline void set_inlined_type_change_checksum(int checksum);
8499 inline bool matches_inlined_type_change_checksum(int checksum);
8500
8501
8502 static inline TypeFeedbackInfo* cast(Object* obj);
8503
8504 // Dispatched behavior.
8505 DECLARE_PRINTER(TypeFeedbackInfo)
8506 DECLARE_VERIFIER(TypeFeedbackInfo)
8507
8508 static const int kStorage1Offset = HeapObject::kHeaderSize;
8509 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8510 static const int kSize = kStorage2Offset + kPointerSize;
8511
8512 // TODO(mvstanton): move these sentinel declarations to shared function info.
8513 // The object that indicates an uninitialized cache.
8514 static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
8515
8516 // The object that indicates a megamorphic state.
8517 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
8518
8519 // The object that indicates a monomorphic state of Array with
8520 // ElementsKind
8521 static inline Handle<Object> MonomorphicArraySentinel(Isolate* isolate,
8522 ElementsKind elements_kind);
8523
8524 // A raw version of the uninitialized sentinel that's safe to read during
8525 // garbage collection (e.g., for patching the cache).
8526 static inline Object* RawUninitializedSentinel(Heap* heap);
8527
8528 private:
8529 static const int kTypeChangeChecksumBits = 7;
8530
8531 class ICTotalCountField: public BitField<int, 0,
8532 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8533 class OwnTypeChangeChecksum: public BitField<int,
8534 kSmiValueSize - kTypeChangeChecksumBits,
8535 kTypeChangeChecksumBits> {}; // NOLINT
8536 class ICsWithTypeInfoCountField: public BitField<int, 0,
8537 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8538 class InlinedTypeChangeChecksum: public BitField<int,
8539 kSmiValueSize - kTypeChangeChecksumBits,
8540 kTypeChangeChecksumBits> {}; // NOLINT
8541
8542 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8543 };
8544
8545
8546 enum AllocationSiteMode {
8547 DONT_TRACK_ALLOCATION_SITE,
8548 TRACK_ALLOCATION_SITE,
8549 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8550 };
8551
8552
8553 class AllocationSite: public Struct {
8554 public:
8555 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8556 static const double kPretenureRatio;
8557 static const int kPretenureMinimumCreated = 100;
8558
8559 // Values for pretenure decision field.
8560 enum PretenureDecision {
8561 kUndecided = 0,
8562 kDontTenure = 1,
8563 kMaybeTenure = 2,
8564 kTenure = 3,
8565 kZombie = 4,
8566 kLastPretenureDecisionValue = kZombie
8567 };
8568
8569 const char* PretenureDecisionName(PretenureDecision decision);
8570
8571 DECL_ACCESSORS(transition_info, Object)
8572 // nested_site threads a list of sites that represent nested literals
8573 // walked in a particular order. So [[1, 2], 1, 2] will have one
8574 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8575 DECL_ACCESSORS(nested_site, Object)
8576 DECL_ACCESSORS(pretenure_data, Smi)
8577 DECL_ACCESSORS(pretenure_create_count, Smi)
8578 DECL_ACCESSORS(dependent_code, DependentCode)
8579 DECL_ACCESSORS(weak_next, Object)
8580
8581 inline void Initialize();
8582
8583 // This method is expensive, it should only be called for reporting.
8584 bool IsNestedSite();
8585
8586 // transition_info bitfields, for constructed array transition info.
8587 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8588 class UnusedBits: public BitField<int, 15, 14> {};
8589 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8590
8591 // Bitfields for pretenure_data
8592 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8593 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8594 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8595 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8596
8597 // Increments the mementos found counter and returns true when the first
8598 // memento was found for a given allocation site.
8599 inline bool IncrementMementoFoundCount();
8600
8601 inline void IncrementMementoCreateCount();
8602
8603 PretenureFlag GetPretenureMode();
8604
8605 void ResetPretenureDecision();
8606
pretenure_decision()8607 PretenureDecision pretenure_decision() {
8608 int value = pretenure_data()->value();
8609 return PretenureDecisionBits::decode(value);
8610 }
8611
set_pretenure_decision(PretenureDecision decision)8612 void set_pretenure_decision(PretenureDecision decision) {
8613 int value = pretenure_data()->value();
8614 set_pretenure_data(
8615 Smi::FromInt(PretenureDecisionBits::update(value, decision)),
8616 SKIP_WRITE_BARRIER);
8617 }
8618
deopt_dependent_code()8619 bool deopt_dependent_code() {
8620 int value = pretenure_data()->value();
8621 return DeoptDependentCodeBit::decode(value);
8622 }
8623
set_deopt_dependent_code(bool deopt)8624 void set_deopt_dependent_code(bool deopt) {
8625 int value = pretenure_data()->value();
8626 set_pretenure_data(
8627 Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)),
8628 SKIP_WRITE_BARRIER);
8629 }
8630
memento_found_count()8631 int memento_found_count() {
8632 int value = pretenure_data()->value();
8633 return MementoFoundCountBits::decode(value);
8634 }
8635
8636 inline void set_memento_found_count(int count);
8637
memento_create_count()8638 int memento_create_count() {
8639 return pretenure_create_count()->value();
8640 }
8641
set_memento_create_count(int count)8642 void set_memento_create_count(int count) {
8643 set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER);
8644 }
8645
8646 // The pretenuring decision is made during gc, and the zombie state allows
8647 // us to recognize when an allocation site is just being kept alive because
8648 // a later traversal of new space may discover AllocationMementos that point
8649 // to this AllocationSite.
IsZombie()8650 bool IsZombie() {
8651 return pretenure_decision() == kZombie;
8652 }
8653
IsMaybeTenure()8654 bool IsMaybeTenure() {
8655 return pretenure_decision() == kMaybeTenure;
8656 }
8657
8658 inline void MarkZombie();
8659
8660 inline bool MakePretenureDecision(PretenureDecision current_decision,
8661 double ratio,
8662 bool maximum_size_scavenge);
8663
8664 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8665
GetElementsKind()8666 ElementsKind GetElementsKind() {
8667 ASSERT(!SitePointsToLiteral());
8668 int value = Smi::cast(transition_info())->value();
8669 return ElementsKindBits::decode(value);
8670 }
8671
SetElementsKind(ElementsKind kind)8672 void SetElementsKind(ElementsKind kind) {
8673 int value = Smi::cast(transition_info())->value();
8674 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)),
8675 SKIP_WRITE_BARRIER);
8676 }
8677
CanInlineCall()8678 bool CanInlineCall() {
8679 int value = Smi::cast(transition_info())->value();
8680 return DoNotInlineBit::decode(value) == 0;
8681 }
8682
SetDoNotInlineCall()8683 void SetDoNotInlineCall() {
8684 int value = Smi::cast(transition_info())->value();
8685 set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)),
8686 SKIP_WRITE_BARRIER);
8687 }
8688
SitePointsToLiteral()8689 bool SitePointsToLiteral() {
8690 // If transition_info is a smi, then it represents an ElementsKind
8691 // for a constructed array. Otherwise, it must be a boilerplate
8692 // for an object or array literal.
8693 return transition_info()->IsJSArray() || transition_info()->IsJSObject();
8694 }
8695
8696 static void DigestTransitionFeedback(Handle<AllocationSite> site,
8697 ElementsKind to_kind);
8698
8699 enum Reason {
8700 TENURING,
8701 TRANSITIONS
8702 };
8703
8704 static void AddDependentCompilationInfo(Handle<AllocationSite> site,
8705 Reason reason,
8706 CompilationInfo* info);
8707
8708 DECLARE_PRINTER(AllocationSite)
8709 DECLARE_VERIFIER(AllocationSite)
8710
8711 static inline AllocationSite* cast(Object* obj);
8712 static inline AllocationSiteMode GetMode(
8713 ElementsKind boilerplate_elements_kind);
8714 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8715 static inline bool CanTrack(InstanceType type);
8716
8717 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8718 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8719 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8720 static const int kPretenureCreateCountOffset =
8721 kPretenureDataOffset + kPointerSize;
8722 static const int kDependentCodeOffset =
8723 kPretenureCreateCountOffset + kPointerSize;
8724 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8725 static const int kSize = kWeakNextOffset + kPointerSize;
8726
8727 // During mark compact we need to take special care for the dependent code
8728 // field.
8729 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
8730 static const int kPointerFieldsEndOffset = kDependentCodeOffset;
8731
8732 // For other visitors, use the fixed body descriptor below.
8733 typedef FixedBodyDescriptor<HeapObject::kHeaderSize,
8734 kDependentCodeOffset + kPointerSize,
8735 kSize> BodyDescriptor;
8736
8737 private:
8738 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason);
PretenuringDecisionMade()8739 bool PretenuringDecisionMade() {
8740 return pretenure_decision() != kUndecided;
8741 }
8742
8743 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8744 };
8745
8746
8747 class AllocationMemento: public Struct {
8748 public:
8749 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8750 static const int kSize = kAllocationSiteOffset + kPointerSize;
8751
DECL_ACCESSORS(allocation_site,Object)8752 DECL_ACCESSORS(allocation_site, Object)
8753
8754 bool IsValid() {
8755 return allocation_site()->IsAllocationSite() &&
8756 !AllocationSite::cast(allocation_site())->IsZombie();
8757 }
GetAllocationSite()8758 AllocationSite* GetAllocationSite() {
8759 ASSERT(IsValid());
8760 return AllocationSite::cast(allocation_site());
8761 }
8762
8763 DECLARE_PRINTER(AllocationMemento)
8764 DECLARE_VERIFIER(AllocationMemento)
8765
8766 static inline AllocationMemento* cast(Object* obj);
8767
8768 private:
8769 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8770 };
8771
8772
8773 // Representation of a slow alias as part of a sloppy arguments objects.
8774 // For fast aliases (if HasSloppyArgumentsElements()):
8775 // - the parameter map contains an index into the context
8776 // - all attributes of the element have default values
8777 // For slow aliases (if HasDictionaryArgumentsElements()):
8778 // - the parameter map contains no fast alias mapping (i.e. the hole)
8779 // - this struct (in the slow backing store) contains an index into the context
8780 // - all attributes are available as part if the property details
8781 class AliasedArgumentsEntry: public Struct {
8782 public:
8783 inline int aliased_context_slot();
8784 inline void set_aliased_context_slot(int count);
8785
8786 static inline AliasedArgumentsEntry* cast(Object* obj);
8787
8788 // Dispatched behavior.
8789 DECLARE_PRINTER(AliasedArgumentsEntry)
8790 DECLARE_VERIFIER(AliasedArgumentsEntry)
8791
8792 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8793 static const int kSize = kAliasedContextSlot + kPointerSize;
8794
8795 private:
8796 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8797 };
8798
8799
8800 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8801 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8802
8803
8804 class StringHasher {
8805 public:
8806 explicit inline StringHasher(int length, uint32_t seed);
8807
8808 template <typename schar>
8809 static inline uint32_t HashSequentialString(const schar* chars,
8810 int length,
8811 uint32_t seed);
8812
8813 // Reads all the data, even for long strings and computes the utf16 length.
8814 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8815 uint32_t seed,
8816 int* utf16_length_out);
8817
8818 // Calculated hash value for a string consisting of 1 to
8819 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8820 // value is represented decimal value.
8821 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
8822
8823 // No string is allowed to have a hash of zero. That value is reserved
8824 // for internal properties. If the hash calculation yields zero then we
8825 // use 27 instead.
8826 static const int kZeroHash = 27;
8827
8828 // Reusable parts of the hashing algorithm.
8829 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8830 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
8831
8832 protected:
8833 // Returns the value to store in the hash field of a string with
8834 // the given length and contents.
8835 uint32_t GetHashField();
8836 // Returns true if the hash of this string can be computed without
8837 // looking at the contents.
8838 inline bool has_trivial_hash();
8839 // Adds a block of characters to the hash.
8840 template<typename Char>
8841 inline void AddCharacters(const Char* chars, int len);
8842
8843 private:
8844 // Add a character to the hash.
8845 inline void AddCharacter(uint16_t c);
8846 // Update index. Returns true if string is still an index.
8847 inline bool UpdateIndex(uint16_t c);
8848
8849 int length_;
8850 uint32_t raw_running_hash_;
8851 uint32_t array_index_;
8852 bool is_array_index_;
8853 bool is_first_char_;
8854 DISALLOW_COPY_AND_ASSIGN(StringHasher);
8855 };
8856
8857
8858 // The characteristics of a string are stored in its map. Retrieving these
8859 // few bits of information is moderately expensive, involving two memory
8860 // loads where the second is dependent on the first. To improve efficiency
8861 // the shape of the string is given its own class so that it can be retrieved
8862 // once and used for several string operations. A StringShape is small enough
8863 // to be passed by value and is immutable, but be aware that flattening a
8864 // string can potentially alter its shape. Also be aware that a GC caused by
8865 // something else can alter the shape of a string due to ConsString
8866 // shortcutting. Keeping these restrictions in mind has proven to be error-
8867 // prone and so we no longer put StringShapes in variables unless there is a
8868 // concrete performance benefit at that particular point in the code.
8869 class StringShape BASE_EMBEDDED {
8870 public:
8871 inline explicit StringShape(String* s);
8872 inline explicit StringShape(Map* s);
8873 inline explicit StringShape(InstanceType t);
8874 inline bool IsSequential();
8875 inline bool IsExternal();
8876 inline bool IsCons();
8877 inline bool IsSliced();
8878 inline bool IsIndirect();
8879 inline bool IsExternalAscii();
8880 inline bool IsExternalTwoByte();
8881 inline bool IsSequentialAscii();
8882 inline bool IsSequentialTwoByte();
8883 inline bool IsInternalized();
8884 inline StringRepresentationTag representation_tag();
8885 inline uint32_t encoding_tag();
8886 inline uint32_t full_representation_tag();
8887 inline uint32_t size_tag();
8888 #ifdef DEBUG
type()8889 inline uint32_t type() { return type_; }
invalidate()8890 inline void invalidate() { valid_ = false; }
valid()8891 inline bool valid() { return valid_; }
8892 #else
invalidate()8893 inline void invalidate() { }
8894 #endif
8895
8896 private:
8897 uint32_t type_;
8898 #ifdef DEBUG
set_valid()8899 inline void set_valid() { valid_ = true; }
8900 bool valid_;
8901 #else
set_valid()8902 inline void set_valid() { }
8903 #endif
8904 };
8905
8906
8907 // The Name abstract class captures anything that can be used as a property
8908 // name, i.e., strings and symbols. All names store a hash value.
8909 class Name: public HeapObject {
8910 public:
8911 // Get and set the hash field of the name.
8912 inline uint32_t hash_field();
8913 inline void set_hash_field(uint32_t value);
8914
8915 // Tells whether the hash code has been computed.
8916 inline bool HasHashCode();
8917
8918 // Returns a hash value used for the property table
8919 inline uint32_t Hash();
8920
8921 // Equality operations.
8922 inline bool Equals(Name* other);
8923 inline static bool Equals(Handle<Name> one, Handle<Name> two);
8924
8925 // Conversion.
8926 inline bool AsArrayIndex(uint32_t* index);
8927
8928 // Casting.
8929 static inline Name* cast(Object* obj);
8930
8931 DECLARE_PRINTER(Name)
8932
8933 // Layout description.
8934 static const int kHashFieldOffset = HeapObject::kHeaderSize;
8935 static const int kSize = kHashFieldOffset + kPointerSize;
8936
8937 // Mask constant for checking if a name has a computed hash code
8938 // and if it is a string that is an array index. The least significant bit
8939 // indicates whether a hash code has been computed. If the hash code has
8940 // been computed the 2nd bit tells whether the string can be used as an
8941 // array index.
8942 static const int kHashNotComputedMask = 1;
8943 static const int kIsNotArrayIndexMask = 1 << 1;
8944 static const int kNofHashBitFields = 2;
8945
8946 // Shift constant retrieving hash code from hash field.
8947 static const int kHashShift = kNofHashBitFields;
8948
8949 // Only these bits are relevant in the hash, since the top two are shifted
8950 // out.
8951 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8952
8953 // Array index strings this short can keep their index in the hash field.
8954 static const int kMaxCachedArrayIndexLength = 7;
8955
8956 // For strings which are array indexes the hash value has the string length
8957 // mixed into the hash, mainly to avoid a hash value of zero which would be
8958 // the case for the string '0'. 24 bits are used for the array index value.
8959 static const int kArrayIndexValueBits = 24;
8960 static const int kArrayIndexLengthBits =
8961 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8962
8963 STATIC_ASSERT((kArrayIndexLengthBits > 0));
8964
8965 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8966 kArrayIndexValueBits> {}; // NOLINT
8967 class ArrayIndexLengthBits : public BitField<unsigned int,
8968 kNofHashBitFields + kArrayIndexValueBits,
8969 kArrayIndexLengthBits> {}; // NOLINT
8970
8971 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8972 // could use a mask to test if the length of string is less than or equal to
8973 // kMaxCachedArrayIndexLength.
8974 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8975
8976 static const unsigned int kContainsCachedArrayIndexMask =
8977 (~kMaxCachedArrayIndexLength << ArrayIndexLengthBits::kShift) |
8978 kIsNotArrayIndexMask;
8979
8980 // Value of empty hash field indicating that the hash is not computed.
8981 static const int kEmptyHashField =
8982 kIsNotArrayIndexMask | kHashNotComputedMask;
8983
8984 protected:
8985 static inline bool IsHashFieldComputed(uint32_t field);
8986
8987 private:
8988 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8989 };
8990
8991
8992 // ES6 symbols.
8993 class Symbol: public Name {
8994 public:
8995 // [name]: the print name of a symbol, or undefined if none.
8996 DECL_ACCESSORS(name, Object)
8997
8998 DECL_ACCESSORS(flags, Smi)
8999
9000 // [is_private]: whether this is a private symbol.
9001 DECL_BOOLEAN_ACCESSORS(is_private)
9002
9003 // Casting.
9004 static inline Symbol* cast(Object* obj);
9005
9006 // Dispatched behavior.
9007 DECLARE_PRINTER(Symbol)
9008 DECLARE_VERIFIER(Symbol)
9009
9010 // Layout description.
9011 static const int kNameOffset = Name::kSize;
9012 static const int kFlagsOffset = kNameOffset + kPointerSize;
9013 static const int kSize = kFlagsOffset + kPointerSize;
9014
9015 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
9016
9017 private:
9018 static const int kPrivateBit = 0;
9019
9020 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
9021 };
9022
9023
9024 class ConsString;
9025
9026 // The String abstract class captures JavaScript string values:
9027 //
9028 // Ecma-262:
9029 // 4.3.16 String Value
9030 // A string value is a member of the type String and is a finite
9031 // ordered sequence of zero or more 16-bit unsigned integer values.
9032 //
9033 // All string values have a length field.
9034 class String: public Name {
9035 public:
9036 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
9037
9038 // Array index strings this short can keep their index in the hash field.
9039 static const int kMaxCachedArrayIndexLength = 7;
9040
9041 // For strings which are array indexes the hash value has the string length
9042 // mixed into the hash, mainly to avoid a hash value of zero which would be
9043 // the case for the string '0'. 24 bits are used for the array index value.
9044 static const int kArrayIndexValueBits = 24;
9045 static const int kArrayIndexLengthBits =
9046 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
9047
9048 STATIC_ASSERT((kArrayIndexLengthBits > 0));
9049
9050 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
9051 kArrayIndexValueBits> {}; // NOLINT
9052 class ArrayIndexLengthBits : public BitField<unsigned int,
9053 kNofHashBitFields + kArrayIndexValueBits,
9054 kArrayIndexLengthBits> {}; // NOLINT
9055
9056 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
9057 // could use a mask to test if the length of string is less than or equal to
9058 // kMaxCachedArrayIndexLength.
9059 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
9060
9061 static const unsigned int kContainsCachedArrayIndexMask =
9062 (~kMaxCachedArrayIndexLength << ArrayIndexLengthBits::kShift) |
9063 kIsNotArrayIndexMask;
9064
9065 // Representation of the flat content of a String.
9066 // A non-flat string doesn't have flat content.
9067 // A flat string has content that's encoded as a sequence of either
9068 // ASCII chars or two-byte UC16.
9069 // Returned by String::GetFlatContent().
9070 class FlatContent {
9071 public:
9072 // Returns true if the string is flat and this structure contains content.
IsFlat()9073 bool IsFlat() { return state_ != NON_FLAT; }
9074 // Returns true if the structure contains ASCII content.
IsAscii()9075 bool IsAscii() { return state_ == ASCII; }
9076 // Returns true if the structure contains two-byte content.
IsTwoByte()9077 bool IsTwoByte() { return state_ == TWO_BYTE; }
9078
9079 // Return the one byte content of the string. Only use if IsAscii() returns
9080 // true.
ToOneByteVector()9081 Vector<const uint8_t> ToOneByteVector() {
9082 ASSERT_EQ(ASCII, state_);
9083 return Vector<const uint8_t>(onebyte_start, length_);
9084 }
9085 // Return the two-byte content of the string. Only use if IsTwoByte()
9086 // returns true.
ToUC16Vector()9087 Vector<const uc16> ToUC16Vector() {
9088 ASSERT_EQ(TWO_BYTE, state_);
9089 return Vector<const uc16>(twobyte_start, length_);
9090 }
9091
Get(int i)9092 uc16 Get(int i) {
9093 ASSERT(i < length_);
9094 ASSERT(state_ != NON_FLAT);
9095 if (state_ == ASCII) return onebyte_start[i];
9096 return twobyte_start[i];
9097 }
9098
9099 private:
9100 enum State { NON_FLAT, ASCII, TWO_BYTE };
9101
9102 // Constructors only used by String::GetFlatContent().
FlatContent(const uint8_t * start,int length)9103 explicit FlatContent(const uint8_t* start, int length)
9104 : onebyte_start(start), length_(length), state_(ASCII) { }
FlatContent(const uc16 * start,int length)9105 explicit FlatContent(const uc16* start, int length)
9106 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
FlatContent()9107 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
9108
9109 union {
9110 const uint8_t* onebyte_start;
9111 const uc16* twobyte_start;
9112 };
9113 int length_;
9114 State state_;
9115
9116 friend class String;
9117 };
9118
9119 // Get and set the length of the string.
9120 inline int length();
9121 inline void set_length(int value);
9122
9123 // Get and set the length of the string using acquire loads and release
9124 // stores.
9125 inline int synchronized_length();
9126 inline void synchronized_set_length(int value);
9127
9128 // Returns whether this string has only ASCII chars, i.e. all of them can
9129 // be ASCII encoded. This might be the case even if the string is
9130 // two-byte. Such strings may appear when the embedder prefers
9131 // two-byte external representations even for ASCII data.
9132 inline bool IsOneByteRepresentation();
9133 inline bool IsTwoByteRepresentation();
9134
9135 // Cons and slices have an encoding flag that may not represent the actual
9136 // encoding of the underlying string. This is taken into account here.
9137 // Requires: this->IsFlat()
9138 inline bool IsOneByteRepresentationUnderneath();
9139 inline bool IsTwoByteRepresentationUnderneath();
9140
9141 // NOTE: this should be considered only a hint. False negatives are
9142 // possible.
9143 inline bool HasOnlyOneByteChars();
9144
9145 // Get and set individual two byte chars in the string.
9146 inline void Set(int index, uint16_t value);
9147 // Get individual two byte char in the string. Repeated calls
9148 // to this method are not efficient unless the string is flat.
9149 INLINE(uint16_t Get(int index));
9150
9151 // Flattens the string. Checks first inline to see if it is
9152 // necessary. Does nothing if the string is not a cons string.
9153 // Flattening allocates a sequential string with the same data as
9154 // the given string and mutates the cons string to a degenerate
9155 // form, where the first component is the new sequential string and
9156 // the second component is the empty string. If allocation fails,
9157 // this function returns a failure. If flattening succeeds, this
9158 // function returns the sequential string that is now the first
9159 // component of the cons string.
9160 //
9161 // Degenerate cons strings are handled specially by the garbage
9162 // collector (see IsShortcutCandidate).
9163
9164 static inline Handle<String> Flatten(Handle<String> string,
9165 PretenureFlag pretenure = NOT_TENURED);
9166
9167 // Tries to return the content of a flat string as a structure holding either
9168 // a flat vector of char or of uc16.
9169 // If the string isn't flat, and therefore doesn't have flat content, the
9170 // returned structure will report so, and can't provide a vector of either
9171 // kind.
9172 FlatContent GetFlatContent();
9173
9174 // Returns the parent of a sliced string or first part of a flat cons string.
9175 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
9176 inline String* GetUnderlying();
9177
9178 // Mark the string as an undetectable object. It only applies to
9179 // ASCII and two byte string types.
9180 bool MarkAsUndetectable();
9181
9182 // String equality operations.
9183 inline bool Equals(String* other);
9184 inline static bool Equals(Handle<String> one, Handle<String> two);
9185 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
9186 bool IsOneByteEqualTo(Vector<const uint8_t> str);
9187 bool IsTwoByteEqualTo(Vector<const uc16> str);
9188
9189 // Return a UTF8 representation of the string. The string is null
9190 // terminated but may optionally contain nulls. Length is returned
9191 // in length_output if length_output is not a null pointer The string
9192 // should be nearly flat, otherwise the performance of this method may
9193 // be very slow (quadratic in the length). Setting robustness_flag to
9194 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
9195 // handles unexpected data without causing assert failures and it does not
9196 // do any heap allocations. This is useful when printing stack traces.
9197 SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
9198 RobustnessFlag robustness_flag,
9199 int offset,
9200 int length,
9201 int* length_output = 0);
9202 SmartArrayPointer<char> ToCString(
9203 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
9204 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
9205 int* length_output = 0);
9206
9207 // Return a 16 bit Unicode representation of the string.
9208 // The string should be nearly flat, otherwise the performance of
9209 // of this method may be very bad. Setting robustness_flag to
9210 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
9211 // handles unexpected data without causing assert failures and it does not
9212 // do any heap allocations. This is useful when printing stack traces.
9213 SmartArrayPointer<uc16> ToWideCString(
9214 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
9215
9216 bool ComputeArrayIndex(uint32_t* index);
9217
9218 // Externalization.
9219 bool MakeExternal(v8::String::ExternalStringResource* resource);
9220 bool MakeExternal(v8::String::ExternalAsciiStringResource* resource);
9221
9222 // Conversion.
9223 inline bool AsArrayIndex(uint32_t* index);
9224
9225 // Casting.
9226 static inline String* cast(Object* obj);
9227
9228 void PrintOn(FILE* out);
9229
9230 // For use during stack traces. Performs rudimentary sanity check.
9231 bool LooksValid();
9232
9233 // Dispatched behavior.
9234 void StringShortPrint(StringStream* accumulator);
9235 #ifdef OBJECT_PRINT
9236 char* ToAsciiArray();
9237 #endif
9238 DECLARE_PRINTER(String)
9239 DECLARE_VERIFIER(String)
9240
9241 inline bool IsFlat();
9242
9243 // Layout description.
9244 static const int kLengthOffset = Name::kSize;
9245 static const int kSize = kLengthOffset + kPointerSize;
9246
9247 // Maximum number of characters to consider when trying to convert a string
9248 // value into an array index.
9249 static const int kMaxArrayIndexSize = 10;
9250 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
9251
9252 // Max char codes.
9253 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
9254 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
9255 static const int kMaxUtf16CodeUnit = 0xffff;
9256 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
9257
9258 // Value of hash field containing computed hash equal to zero.
9259 static const int kEmptyStringHash = kIsNotArrayIndexMask;
9260
9261 // Maximal string length.
9262 static const int kMaxLength = (1 << 28) - 16;
9263
9264 // Max length for computing hash. For strings longer than this limit the
9265 // string length is used as the hash value.
9266 static const int kMaxHashCalcLength = 16383;
9267
9268 // Limit for truncation in short printing.
9269 static const int kMaxShortPrintLength = 1024;
9270
9271 // Support for regular expressions.
9272 const uc16* GetTwoByteData(unsigned start);
9273
9274 // Helper function for flattening strings.
9275 template <typename sinkchar>
9276 static void WriteToFlat(String* source,
9277 sinkchar* sink,
9278 int from,
9279 int to);
9280
9281 // The return value may point to the first aligned word containing the
9282 // first non-ascii character, rather than directly to the non-ascii character.
9283 // If the return value is >= the passed length, the entire string was ASCII.
NonAsciiStart(const char * chars,int length)9284 static inline int NonAsciiStart(const char* chars, int length) {
9285 const char* start = chars;
9286 const char* limit = chars + length;
9287 #ifdef V8_HOST_CAN_READ_UNALIGNED
9288 ASSERT(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9289 const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9290 while (chars + sizeof(uintptr_t) <= limit) {
9291 if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
9292 return static_cast<int>(chars - start);
9293 }
9294 chars += sizeof(uintptr_t);
9295 }
9296 #endif
9297 while (chars < limit) {
9298 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9299 return static_cast<int>(chars - start);
9300 }
9301 ++chars;
9302 }
9303 return static_cast<int>(chars - start);
9304 }
9305
IsAscii(const char * chars,int length)9306 static inline bool IsAscii(const char* chars, int length) {
9307 return NonAsciiStart(chars, length) >= length;
9308 }
9309
IsAscii(const uint8_t * chars,int length)9310 static inline bool IsAscii(const uint8_t* chars, int length) {
9311 return
9312 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
9313 }
9314
NonOneByteStart(const uc16 * chars,int length)9315 static inline int NonOneByteStart(const uc16* chars, int length) {
9316 const uc16* limit = chars + length;
9317 const uc16* start = chars;
9318 while (chars < limit) {
9319 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
9320 ++chars;
9321 }
9322 return static_cast<int>(chars - start);
9323 }
9324
IsOneByte(const uc16 * chars,int length)9325 static inline bool IsOneByte(const uc16* chars, int length) {
9326 return NonOneByteStart(chars, length) >= length;
9327 }
9328
9329 template<class Visitor>
9330 static inline ConsString* VisitFlat(Visitor* visitor,
9331 String* string,
9332 int offset = 0);
9333
9334 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
9335 bool include_ending_line);
9336
9337 private:
9338 friend class Name;
9339
9340 static Handle<String> SlowFlatten(Handle<ConsString> cons,
9341 PretenureFlag tenure);
9342
9343 // Slow case of String::Equals. This implementation works on any strings
9344 // but it is most efficient on strings that are almost flat.
9345 bool SlowEquals(String* other);
9346
9347 static bool SlowEquals(Handle<String> one, Handle<String> two);
9348
9349 // Slow case of AsArrayIndex.
9350 bool SlowAsArrayIndex(uint32_t* index);
9351
9352 // Compute and set the hash code.
9353 uint32_t ComputeAndSetHash();
9354
9355 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
9356 };
9357
9358
9359 // The SeqString abstract class captures sequential string values.
9360 class SeqString: public String {
9361 public:
9362 // Casting.
9363 static inline SeqString* cast(Object* obj);
9364
9365 // Layout description.
9366 static const int kHeaderSize = String::kSize;
9367
9368 // Truncate the string in-place if possible and return the result.
9369 // In case of new_length == 0, the empty string is returned without
9370 // truncating the original string.
9371 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
9372 int new_length);
9373 private:
9374 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
9375 };
9376
9377
9378 // The AsciiString class captures sequential ASCII string objects.
9379 // Each character in the AsciiString is an ASCII character.
9380 class SeqOneByteString: public SeqString {
9381 public:
9382 static const bool kHasAsciiEncoding = true;
9383
9384 // Dispatched behavior.
9385 inline uint16_t SeqOneByteStringGet(int index);
9386 inline void SeqOneByteStringSet(int index, uint16_t value);
9387
9388 // Get the address of the characters in this string.
9389 inline Address GetCharsAddress();
9390
9391 inline uint8_t* GetChars();
9392
9393 // Casting
9394 static inline SeqOneByteString* cast(Object* obj);
9395
9396 // Garbage collection support. This method is called by the
9397 // garbage collector to compute the actual size of an AsciiString
9398 // instance.
9399 inline int SeqOneByteStringSize(InstanceType instance_type);
9400
9401 // Computes the size for an AsciiString instance of a given length.
SizeFor(int length)9402 static int SizeFor(int length) {
9403 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
9404 }
9405
9406 // Maximal memory usage for a single sequential ASCII string.
9407 static const int kMaxSize = 512 * MB - 1;
9408 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
9409
9410 private:
9411 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
9412 };
9413
9414
9415 // The TwoByteString class captures sequential unicode string objects.
9416 // Each character in the TwoByteString is a two-byte uint16_t.
9417 class SeqTwoByteString: public SeqString {
9418 public:
9419 static const bool kHasAsciiEncoding = false;
9420
9421 // Dispatched behavior.
9422 inline uint16_t SeqTwoByteStringGet(int index);
9423 inline void SeqTwoByteStringSet(int index, uint16_t value);
9424
9425 // Get the address of the characters in this string.
9426 inline Address GetCharsAddress();
9427
9428 inline uc16* GetChars();
9429
9430 // For regexp code.
9431 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9432
9433 // Casting
9434 static inline SeqTwoByteString* cast(Object* obj);
9435
9436 // Garbage collection support. This method is called by the
9437 // garbage collector to compute the actual size of a TwoByteString
9438 // instance.
9439 inline int SeqTwoByteStringSize(InstanceType instance_type);
9440
9441 // Computes the size for a TwoByteString instance of a given length.
SizeFor(int length)9442 static int SizeFor(int length) {
9443 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
9444 }
9445
9446 // Maximal memory usage for a single sequential two-byte string.
9447 static const int kMaxSize = 512 * MB - 1;
9448 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9449 String::kMaxLength);
9450
9451 private:
9452 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9453 };
9454
9455
9456 // The ConsString class describes string values built by using the
9457 // addition operator on strings. A ConsString is a pair where the
9458 // first and second components are pointers to other string values.
9459 // One or both components of a ConsString can be pointers to other
9460 // ConsStrings, creating a binary tree of ConsStrings where the leaves
9461 // are non-ConsString string values. The string value represented by
9462 // a ConsString can be obtained by concatenating the leaf string
9463 // values in a left-to-right depth-first traversal of the tree.
9464 class ConsString: public String {
9465 public:
9466 // First string of the cons cell.
9467 inline String* first();
9468 // Doesn't check that the result is a string, even in debug mode. This is
9469 // useful during GC where the mark bits confuse the checks.
9470 inline Object* unchecked_first();
9471 inline void set_first(String* first,
9472 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9473
9474 // Second string of the cons cell.
9475 inline String* second();
9476 // Doesn't check that the result is a string, even in debug mode. This is
9477 // useful during GC where the mark bits confuse the checks.
9478 inline Object* unchecked_second();
9479 inline void set_second(String* second,
9480 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9481
9482 // Dispatched behavior.
9483 uint16_t ConsStringGet(int index);
9484
9485 // Casting.
9486 static inline ConsString* cast(Object* obj);
9487
9488 // Layout description.
9489 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9490 static const int kSecondOffset = kFirstOffset + kPointerSize;
9491 static const int kSize = kSecondOffset + kPointerSize;
9492
9493 // Minimum length for a cons string.
9494 static const int kMinLength = 13;
9495
9496 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9497 BodyDescriptor;
9498
9499 DECLARE_VERIFIER(ConsString)
9500
9501 private:
9502 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9503 };
9504
9505
9506 // The Sliced String class describes strings that are substrings of another
9507 // sequential string. The motivation is to save time and memory when creating
9508 // a substring. A Sliced String is described as a pointer to the parent,
9509 // the offset from the start of the parent string and the length. Using
9510 // a Sliced String therefore requires unpacking of the parent string and
9511 // adding the offset to the start address. A substring of a Sliced String
9512 // are not nested since the double indirection is simplified when creating
9513 // such a substring.
9514 // Currently missing features are:
9515 // - handling externalized parent strings
9516 // - external strings as parent
9517 // - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9518 class SlicedString: public String {
9519 public:
9520 inline String* parent();
9521 inline void set_parent(String* parent,
9522 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9523 inline int offset();
9524 inline void set_offset(int offset);
9525
9526 // Dispatched behavior.
9527 uint16_t SlicedStringGet(int index);
9528
9529 // Casting.
9530 static inline SlicedString* cast(Object* obj);
9531
9532 // Layout description.
9533 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9534 static const int kOffsetOffset = kParentOffset + kPointerSize;
9535 static const int kSize = kOffsetOffset + kPointerSize;
9536
9537 // Minimum length for a sliced string.
9538 static const int kMinLength = 13;
9539
9540 typedef FixedBodyDescriptor<kParentOffset,
9541 kOffsetOffset + kPointerSize, kSize>
9542 BodyDescriptor;
9543
9544 DECLARE_VERIFIER(SlicedString)
9545
9546 private:
9547 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9548 };
9549
9550
9551 // The ExternalString class describes string values that are backed by
9552 // a string resource that lies outside the V8 heap. ExternalStrings
9553 // consist of the length field common to all strings, a pointer to the
9554 // external resource. It is important to ensure (externally) that the
9555 // resource is not deallocated while the ExternalString is live in the
9556 // V8 heap.
9557 //
9558 // The API expects that all ExternalStrings are created through the
9559 // API. Therefore, ExternalStrings should not be used internally.
9560 class ExternalString: public String {
9561 public:
9562 // Casting
9563 static inline ExternalString* cast(Object* obj);
9564
9565 // Layout description.
9566 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
9567 static const int kShortSize = kResourceOffset + kPointerSize;
9568 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9569 static const int kSize = kResourceDataOffset + kPointerSize;
9570
9571 static const int kMaxShortLength =
9572 (kShortSize - SeqString::kHeaderSize) / kCharSize;
9573
9574 // Return whether external string is short (data pointer is not cached).
9575 inline bool is_short();
9576
9577 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
9578
9579 private:
9580 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9581 };
9582
9583
9584 // The ExternalAsciiString class is an external string backed by an
9585 // ASCII string.
9586 class ExternalAsciiString: public ExternalString {
9587 public:
9588 static const bool kHasAsciiEncoding = true;
9589
9590 typedef v8::String::ExternalAsciiStringResource Resource;
9591
9592 // The underlying resource.
9593 inline const Resource* resource();
9594 inline void set_resource(const Resource* buffer);
9595
9596 // Update the pointer cache to the external character array.
9597 // The cached pointer is always valid, as the external character array does =
9598 // not move during lifetime. Deserialization is the only exception, after
9599 // which the pointer cache has to be refreshed.
9600 inline void update_data_cache();
9601
9602 inline const uint8_t* GetChars();
9603
9604 // Dispatched behavior.
9605 inline uint16_t ExternalAsciiStringGet(int index);
9606
9607 // Casting.
9608 static inline ExternalAsciiString* cast(Object* obj);
9609
9610 // Garbage collection support.
9611 inline void ExternalAsciiStringIterateBody(ObjectVisitor* v);
9612
9613 template<typename StaticVisitor>
9614 inline void ExternalAsciiStringIterateBody();
9615
9616 private:
9617 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString);
9618 };
9619
9620
9621 // The ExternalTwoByteString class is an external string backed by a UTF-16
9622 // encoded string.
9623 class ExternalTwoByteString: public ExternalString {
9624 public:
9625 static const bool kHasAsciiEncoding = false;
9626
9627 typedef v8::String::ExternalStringResource Resource;
9628
9629 // The underlying string resource.
9630 inline const Resource* resource();
9631 inline void set_resource(const Resource* buffer);
9632
9633 // Update the pointer cache to the external character array.
9634 // The cached pointer is always valid, as the external character array does =
9635 // not move during lifetime. Deserialization is the only exception, after
9636 // which the pointer cache has to be refreshed.
9637 inline void update_data_cache();
9638
9639 inline const uint16_t* GetChars();
9640
9641 // Dispatched behavior.
9642 inline uint16_t ExternalTwoByteStringGet(int index);
9643
9644 // For regexp code.
9645 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
9646
9647 // Casting.
9648 static inline ExternalTwoByteString* cast(Object* obj);
9649
9650 // Garbage collection support.
9651 inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
9652
9653 template<typename StaticVisitor>
9654 inline void ExternalTwoByteStringIterateBody();
9655
9656 private:
9657 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9658 };
9659
9660
9661 // Utility superclass for stack-allocated objects that must be updated
9662 // on gc. It provides two ways for the gc to update instances, either
9663 // iterating or updating after gc.
9664 class Relocatable BASE_EMBEDDED {
9665 public:
9666 explicit inline Relocatable(Isolate* isolate);
9667 inline virtual ~Relocatable();
IterateInstance(ObjectVisitor * v)9668 virtual void IterateInstance(ObjectVisitor* v) { }
PostGarbageCollection()9669 virtual void PostGarbageCollection() { }
9670
9671 static void PostGarbageCollectionProcessing(Isolate* isolate);
9672 static int ArchiveSpacePerThread();
9673 static char* ArchiveState(Isolate* isolate, char* to);
9674 static char* RestoreState(Isolate* isolate, char* from);
9675 static void Iterate(Isolate* isolate, ObjectVisitor* v);
9676 static void Iterate(ObjectVisitor* v, Relocatable* top);
9677 static char* Iterate(ObjectVisitor* v, char* t);
9678
9679 private:
9680 Isolate* isolate_;
9681 Relocatable* prev_;
9682 };
9683
9684
9685 // A flat string reader provides random access to the contents of a
9686 // string independent of the character width of the string. The handle
9687 // must be valid as long as the reader is being used.
9688 class FlatStringReader : public Relocatable {
9689 public:
9690 FlatStringReader(Isolate* isolate, Handle<String> str);
9691 FlatStringReader(Isolate* isolate, Vector<const char> input);
9692 void PostGarbageCollection();
9693 inline uc32 Get(int index);
length()9694 int length() { return length_; }
9695 private:
9696 String** str_;
9697 bool is_ascii_;
9698 int length_;
9699 const void* start_;
9700 };
9701
9702
9703 // A ConsStringOp that returns null.
9704 // Useful when the operation to apply on a ConsString
9705 // requires an expensive data structure.
9706 class ConsStringNullOp {
9707 public:
ConsStringNullOp()9708 inline ConsStringNullOp() {}
9709 static inline String* Operate(String*, unsigned*, int32_t*, unsigned*);
9710 private:
9711 DISALLOW_COPY_AND_ASSIGN(ConsStringNullOp);
9712 };
9713
9714
9715 // This maintains an off-stack representation of the stack frames required
9716 // to traverse a ConsString, allowing an entirely iterative and restartable
9717 // traversal of the entire string
9718 class ConsStringIteratorOp {
9719 public:
ConsStringIteratorOp()9720 inline ConsStringIteratorOp() {}
9721 inline ConsStringIteratorOp(ConsString* cons_string, int offset = 0) {
9722 Reset(cons_string, offset);
9723 }
9724 inline void Reset(ConsString* cons_string, int offset = 0) {
9725 depth_ = 0;
9726 // Next will always return NULL.
9727 if (cons_string == NULL) return;
9728 Initialize(cons_string, offset);
9729 }
9730 // Returns NULL when complete.
Next(int * offset_out)9731 inline String* Next(int* offset_out) {
9732 *offset_out = 0;
9733 if (depth_ == 0) return NULL;
9734 return Continue(offset_out);
9735 }
9736
9737 private:
9738 static const int kStackSize = 32;
9739 // Use a mask instead of doing modulo operations for stack wrapping.
9740 static const int kDepthMask = kStackSize-1;
9741 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9742 static inline int OffsetForDepth(int depth);
9743
9744 inline void PushLeft(ConsString* string);
9745 inline void PushRight(ConsString* string);
9746 inline void AdjustMaximumDepth();
9747 inline void Pop();
StackBlown()9748 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
9749 void Initialize(ConsString* cons_string, int offset);
9750 String* Continue(int* offset_out);
9751 String* NextLeaf(bool* blew_stack);
9752 String* Search(int* offset_out);
9753
9754 // Stack must always contain only frames for which right traversal
9755 // has not yet been performed.
9756 ConsString* frames_[kStackSize];
9757 ConsString* root_;
9758 int depth_;
9759 int maximum_depth_;
9760 int consumed_;
9761 DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
9762 };
9763
9764
9765 class StringCharacterStream {
9766 public:
9767 inline StringCharacterStream(String* string,
9768 ConsStringIteratorOp* op,
9769 int offset = 0);
9770 inline uint16_t GetNext();
9771 inline bool HasMore();
9772 inline void Reset(String* string, int offset = 0);
9773 inline void VisitOneByteString(const uint8_t* chars, int length);
9774 inline void VisitTwoByteString(const uint16_t* chars, int length);
9775
9776 private:
9777 bool is_one_byte_;
9778 union {
9779 const uint8_t* buffer8_;
9780 const uint16_t* buffer16_;
9781 };
9782 const uint8_t* end_;
9783 ConsStringIteratorOp* op_;
9784 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
9785 };
9786
9787
9788 template <typename T>
9789 class VectorIterator {
9790 public:
VectorIterator(T * d,int l)9791 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
VectorIterator(Vector<const T> data)9792 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
GetNext()9793 T GetNext() { return data_[index_++]; }
has_more()9794 bool has_more() { return index_ < data_.length(); }
9795 private:
9796 Vector<const T> data_;
9797 int index_;
9798 };
9799
9800
9801 // The Oddball describes objects null, undefined, true, and false.
9802 class Oddball: public HeapObject {
9803 public:
9804 // [to_string]: Cached to_string computed at startup.
9805 DECL_ACCESSORS(to_string, String)
9806
9807 // [to_number]: Cached to_number computed at startup.
9808 DECL_ACCESSORS(to_number, Object)
9809
9810 inline byte kind();
9811 inline void set_kind(byte kind);
9812
9813 // Casting.
9814 static inline Oddball* cast(Object* obj);
9815
9816 // Dispatched behavior.
9817 DECLARE_VERIFIER(Oddball)
9818
9819 // Initialize the fields.
9820 static void Initialize(Isolate* isolate,
9821 Handle<Oddball> oddball,
9822 const char* to_string,
9823 Handle<Object> to_number,
9824 byte kind);
9825
9826 // Layout description.
9827 static const int kToStringOffset = HeapObject::kHeaderSize;
9828 static const int kToNumberOffset = kToStringOffset + kPointerSize;
9829 static const int kKindOffset = kToNumberOffset + kPointerSize;
9830 static const int kSize = kKindOffset + kPointerSize;
9831
9832 static const byte kFalse = 0;
9833 static const byte kTrue = 1;
9834 static const byte kNotBooleanMask = ~1;
9835 static const byte kTheHole = 2;
9836 static const byte kNull = 3;
9837 static const byte kArgumentMarker = 4;
9838 static const byte kUndefined = 5;
9839 static const byte kUninitialized = 6;
9840 static const byte kOther = 7;
9841 static const byte kException = 8;
9842
9843 typedef FixedBodyDescriptor<kToStringOffset,
9844 kToNumberOffset + kPointerSize,
9845 kSize> BodyDescriptor;
9846
9847 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
9848 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
9849 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
9850
9851 private:
9852 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9853 };
9854
9855
9856 class Cell: public HeapObject {
9857 public:
9858 // [value]: value of the global property.
9859 DECL_ACCESSORS(value, Object)
9860
9861 // Casting.
9862 static inline Cell* cast(Object* obj);
9863
FromValueAddress(Address value)9864 static inline Cell* FromValueAddress(Address value) {
9865 Object* result = FromAddress(value - kValueOffset);
9866 ASSERT(result->IsCell() || result->IsPropertyCell());
9867 return static_cast<Cell*>(result);
9868 }
9869
ValueAddress()9870 inline Address ValueAddress() {
9871 return address() + kValueOffset;
9872 }
9873
9874 // Dispatched behavior.
9875 DECLARE_PRINTER(Cell)
9876 DECLARE_VERIFIER(Cell)
9877
9878 // Layout description.
9879 static const int kValueOffset = HeapObject::kHeaderSize;
9880 static const int kSize = kValueOffset + kPointerSize;
9881
9882 typedef FixedBodyDescriptor<kValueOffset,
9883 kValueOffset + kPointerSize,
9884 kSize> BodyDescriptor;
9885
9886 private:
9887 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9888 };
9889
9890
9891 class PropertyCell: public Cell {
9892 public:
9893 // [type]: type of the global property.
9894 HeapType* type();
9895 void set_type(HeapType* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9896
9897 // [dependent_code]: dependent code that depends on the type of the global
9898 // property.
9899 DECL_ACCESSORS(dependent_code, DependentCode)
9900
9901 // Sets the value of the cell and updates the type field to be the union
9902 // of the cell's current type and the value's type. If the change causes
9903 // a change of the type of the cell's contents, code dependent on the cell
9904 // will be deoptimized.
9905 static void SetValueInferType(Handle<PropertyCell> cell,
9906 Handle<Object> value);
9907
9908 // Computes the new type of the cell's contents for the given value, but
9909 // without actually modifying the 'type' field.
9910 static Handle<HeapType> UpdatedType(Handle<PropertyCell> cell,
9911 Handle<Object> value);
9912
9913 static void AddDependentCompilationInfo(Handle<PropertyCell> cell,
9914 CompilationInfo* info);
9915
9916 // Casting.
9917 static inline PropertyCell* cast(Object* obj);
9918
TypeAddress()9919 inline Address TypeAddress() {
9920 return address() + kTypeOffset;
9921 }
9922
9923 // Dispatched behavior.
9924 DECLARE_PRINTER(PropertyCell)
9925 DECLARE_VERIFIER(PropertyCell)
9926
9927 // Layout description.
9928 static const int kTypeOffset = kValueOffset + kPointerSize;
9929 static const int kDependentCodeOffset = kTypeOffset + kPointerSize;
9930 static const int kSize = kDependentCodeOffset + kPointerSize;
9931
9932 static const int kPointerFieldsBeginOffset = kValueOffset;
9933 static const int kPointerFieldsEndOffset = kDependentCodeOffset;
9934
9935 typedef FixedBodyDescriptor<kValueOffset,
9936 kSize,
9937 kSize> BodyDescriptor;
9938
9939 private:
9940 DECL_ACCESSORS(type_raw, Object)
9941 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
9942 };
9943
9944
9945 // The JSProxy describes EcmaScript Harmony proxies
9946 class JSProxy: public JSReceiver {
9947 public:
9948 // [handler]: The handler property.
9949 DECL_ACCESSORS(handler, Object)
9950
9951 // [hash]: The hash code property (undefined if not initialized yet).
9952 DECL_ACCESSORS(hash, Object)
9953
9954 // Casting.
9955 static inline JSProxy* cast(Object* obj);
9956
9957 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithHandler(
9958 Handle<JSProxy> proxy,
9959 Handle<Object> receiver,
9960 Handle<Name> name);
9961 MUST_USE_RESULT static inline MaybeHandle<Object> GetElementWithHandler(
9962 Handle<JSProxy> proxy,
9963 Handle<Object> receiver,
9964 uint32_t index);
9965
9966 // If the handler defines an accessor property with a setter, invoke it.
9967 // If it defines an accessor property without a setter, or a data property
9968 // that is read-only, throw. In all these cases set '*done' to true,
9969 // otherwise set it to false.
9970 MUST_USE_RESULT
9971 static MaybeHandle<Object> SetPropertyViaPrototypesWithHandler(
9972 Handle<JSProxy> proxy,
9973 Handle<JSReceiver> receiver,
9974 Handle<Name> name,
9975 Handle<Object> value,
9976 PropertyAttributes attributes,
9977 StrictMode strict_mode,
9978 bool* done);
9979
9980 static PropertyAttributes GetPropertyAttributesWithHandler(
9981 Handle<JSProxy> proxy,
9982 Handle<Object> receiver,
9983 Handle<Name> name);
9984 static PropertyAttributes GetElementAttributeWithHandler(
9985 Handle<JSProxy> proxy,
9986 Handle<JSReceiver> receiver,
9987 uint32_t index);
9988
9989 // Turn the proxy into an (empty) JSObject.
9990 static void Fix(Handle<JSProxy> proxy);
9991
9992 // Initializes the body after the handler slot.
9993 inline void InitializeBody(int object_size, Object* value);
9994
9995 // Invoke a trap by name. If the trap does not exist on this's handler,
9996 // but derived_trap is non-NULL, invoke that instead. May cause GC.
9997 MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
9998 Handle<JSProxy> proxy,
9999 const char* name,
10000 Handle<Object> derived_trap,
10001 int argc,
10002 Handle<Object> args[]);
10003
10004 // Dispatched behavior.
10005 DECLARE_PRINTER(JSProxy)
10006 DECLARE_VERIFIER(JSProxy)
10007
10008 // Layout description. We add padding so that a proxy has the same
10009 // size as a virgin JSObject. This is essential for becoming a JSObject
10010 // upon freeze.
10011 static const int kHandlerOffset = HeapObject::kHeaderSize;
10012 static const int kHashOffset = kHandlerOffset + kPointerSize;
10013 static const int kPaddingOffset = kHashOffset + kPointerSize;
10014 static const int kSize = JSObject::kHeaderSize;
10015 static const int kHeaderSize = kPaddingOffset;
10016 static const int kPaddingSize = kSize - kPaddingOffset;
10017
10018 STATIC_ASSERT(kPaddingSize >= 0);
10019
10020 typedef FixedBodyDescriptor<kHandlerOffset,
10021 kPaddingOffset,
10022 kSize> BodyDescriptor;
10023
10024 private:
10025 friend class JSReceiver;
10026
10027 MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
10028 Handle<JSProxy> proxy,
10029 Handle<JSReceiver> receiver,
10030 Handle<Name> name,
10031 Handle<Object> value,
10032 PropertyAttributes attributes,
10033 StrictMode strict_mode);
10034 MUST_USE_RESULT static inline MaybeHandle<Object> SetElementWithHandler(
10035 Handle<JSProxy> proxy,
10036 Handle<JSReceiver> receiver,
10037 uint32_t index,
10038 Handle<Object> value,
10039 StrictMode strict_mode);
10040
10041 static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
10042 static inline bool HasElementWithHandler(Handle<JSProxy> proxy,
10043 uint32_t index);
10044
10045 MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
10046 Handle<JSProxy> proxy,
10047 Handle<Name> name,
10048 DeleteMode mode);
10049 MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithHandler(
10050 Handle<JSProxy> proxy,
10051 uint32_t index,
10052 DeleteMode mode);
10053
10054 MUST_USE_RESULT Object* GetIdentityHash();
10055
10056 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
10057
10058 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
10059 };
10060
10061
10062 class JSFunctionProxy: public JSProxy {
10063 public:
10064 // [call_trap]: The call trap.
10065 DECL_ACCESSORS(call_trap, Object)
10066
10067 // [construct_trap]: The construct trap.
10068 DECL_ACCESSORS(construct_trap, Object)
10069
10070 // Casting.
10071 static inline JSFunctionProxy* cast(Object* obj);
10072
10073 // Dispatched behavior.
10074 DECLARE_PRINTER(JSFunctionProxy)
10075 DECLARE_VERIFIER(JSFunctionProxy)
10076
10077 // Layout description.
10078 static const int kCallTrapOffset = JSProxy::kPaddingOffset;
10079 static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize;
10080 static const int kPaddingOffset = kConstructTrapOffset + kPointerSize;
10081 static const int kSize = JSFunction::kSize;
10082 static const int kPaddingSize = kSize - kPaddingOffset;
10083
10084 STATIC_ASSERT(kPaddingSize >= 0);
10085
10086 typedef FixedBodyDescriptor<kHandlerOffset,
10087 kConstructTrapOffset + kPointerSize,
10088 kSize> BodyDescriptor;
10089
10090 private:
10091 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
10092 };
10093
10094
10095 // The JSSet describes EcmaScript Harmony sets
10096 class JSSet: public JSObject {
10097 public:
10098 // [set]: the backing hash set containing keys.
10099 DECL_ACCESSORS(table, Object)
10100
10101 // Casting.
10102 static inline JSSet* cast(Object* obj);
10103
10104 // Dispatched behavior.
10105 DECLARE_PRINTER(JSSet)
10106 DECLARE_VERIFIER(JSSet)
10107
10108 static const int kTableOffset = JSObject::kHeaderSize;
10109 static const int kSize = kTableOffset + kPointerSize;
10110
10111 private:
10112 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
10113 };
10114
10115
10116 // The JSMap describes EcmaScript Harmony maps
10117 class JSMap: public JSObject {
10118 public:
10119 // [table]: the backing hash table mapping keys to values.
10120 DECL_ACCESSORS(table, Object)
10121
10122 // Casting.
10123 static inline JSMap* cast(Object* obj);
10124
10125 // Dispatched behavior.
10126 DECLARE_PRINTER(JSMap)
10127 DECLARE_VERIFIER(JSMap)
10128
10129 static const int kTableOffset = JSObject::kHeaderSize;
10130 static const int kSize = kTableOffset + kPointerSize;
10131
10132 private:
10133 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
10134 };
10135
10136
10137 // OrderedHashTableIterator is an iterator that iterates over the keys and
10138 // values of an OrderedHashTable.
10139 //
10140 // The iterator has a reference to the underlying OrderedHashTable data,
10141 // [table], as well as the current [index] the iterator is at.
10142 //
10143 // When the OrderedHashTable is rehashed it adds a reference from the old table
10144 // to the new table as well as storing enough data about the changes so that the
10145 // iterator [index] can be adjusted accordingly.
10146 //
10147 // When the [Next] result from the iterator is requested, the iterator checks if
10148 // there is a newer table that it needs to transition to.
10149 template<class Derived, class TableType>
10150 class OrderedHashTableIterator: public JSObject {
10151 public:
10152 // [table]: the backing hash table mapping keys to values.
10153 DECL_ACCESSORS(table, Object)
10154
10155 // [index]: The index into the data table.
10156 DECL_ACCESSORS(index, Smi)
10157
10158 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
10159 DECL_ACCESSORS(kind, Smi)
10160
10161 #ifdef OBJECT_PRINT
10162 void OrderedHashTableIteratorPrint(FILE* out);
10163 #endif
10164
10165 static const int kTableOffset = JSObject::kHeaderSize;
10166 static const int kIndexOffset = kTableOffset + kPointerSize;
10167 static const int kKindOffset = kIndexOffset + kPointerSize;
10168 static const int kSize = kKindOffset + kPointerSize;
10169
10170 enum Kind {
10171 kKindKeys = 1,
10172 kKindValues = 2,
10173 kKindEntries = 3
10174 };
10175
10176 // Returns an iterator result object: {value: any, done: boolean} and moves
10177 // the index to the next valid entry. Closes the iterator if moving past the
10178 // end.
10179 static Handle<JSObject> Next(Handle<Derived> iterator);
10180
10181 private:
10182 // Transitions the iterator to the non obsolote backing store. This is a NOP
10183 // if the [table] is not obsolete.
10184 void Transition();
10185
10186 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
10187 };
10188
10189
10190 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
10191 OrderedHashSet> {
10192 public:
10193 // Dispatched behavior.
10194 DECLARE_PRINTER(JSSetIterator)
10195 DECLARE_VERIFIER(JSSetIterator)
10196
10197 // Casting.
10198 static inline JSSetIterator* cast(Object* obj);
10199
10200 static Handle<Object> ValueForKind(
10201 Handle<JSSetIterator> iterator,
10202 int entry_index);
10203
10204 private:
10205 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
10206 };
10207
10208
10209 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
10210 OrderedHashMap> {
10211 public:
10212 // Dispatched behavior.
10213 DECLARE_PRINTER(JSMapIterator)
10214 DECLARE_VERIFIER(JSMapIterator)
10215
10216 // Casting.
10217 static inline JSMapIterator* cast(Object* obj);
10218
10219 static Handle<Object> ValueForKind(
10220 Handle<JSMapIterator> iterator,
10221 int entry_index);
10222
10223 private:
10224 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
10225 };
10226
10227
10228 // Base class for both JSWeakMap and JSWeakSet
10229 class JSWeakCollection: public JSObject {
10230 public:
10231 // [table]: the backing hash table mapping keys to values.
10232 DECL_ACCESSORS(table, Object)
10233
10234 // [next]: linked list of encountered weak maps during GC.
10235 DECL_ACCESSORS(next, Object)
10236
10237 static const int kTableOffset = JSObject::kHeaderSize;
10238 static const int kNextOffset = kTableOffset + kPointerSize;
10239 static const int kSize = kNextOffset + kPointerSize;
10240
10241 private:
10242 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
10243 };
10244
10245
10246 // The JSWeakMap describes EcmaScript Harmony weak maps
10247 class JSWeakMap: public JSWeakCollection {
10248 public:
10249 // Casting.
10250 static inline JSWeakMap* cast(Object* obj);
10251
10252 // Dispatched behavior.
10253 DECLARE_PRINTER(JSWeakMap)
10254 DECLARE_VERIFIER(JSWeakMap)
10255
10256 private:
10257 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
10258 };
10259
10260
10261 // The JSWeakSet describes EcmaScript Harmony weak sets
10262 class JSWeakSet: public JSWeakCollection {
10263 public:
10264 // Casting.
10265 static inline JSWeakSet* cast(Object* obj);
10266
10267 // Dispatched behavior.
10268 DECLARE_PRINTER(JSWeakSet)
10269 DECLARE_VERIFIER(JSWeakSet)
10270
10271 private:
10272 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
10273 };
10274
10275
10276 class JSArrayBuffer: public JSObject {
10277 public:
10278 // [backing_store]: backing memory for this array
10279 DECL_ACCESSORS(backing_store, void)
10280
10281 // [byte_length]: length in bytes
10282 DECL_ACCESSORS(byte_length, Object)
10283
10284 // [flags]
10285 DECL_ACCESSORS(flag, Smi)
10286
10287 inline bool is_external();
10288 inline void set_is_external(bool value);
10289
10290 inline bool should_be_freed();
10291 inline void set_should_be_freed(bool value);
10292
10293 // [weak_next]: linked list of array buffers.
10294 DECL_ACCESSORS(weak_next, Object)
10295
10296 // [weak_first_array]: weak linked list of views.
10297 DECL_ACCESSORS(weak_first_view, Object)
10298
10299 // Casting.
10300 static inline JSArrayBuffer* cast(Object* obj);
10301
10302 // Neutering. Only neuters the buffer, not associated typed arrays.
10303 void Neuter();
10304
10305 // Dispatched behavior.
10306 DECLARE_PRINTER(JSArrayBuffer)
10307 DECLARE_VERIFIER(JSArrayBuffer)
10308
10309 static const int kBackingStoreOffset = JSObject::kHeaderSize;
10310 static const int kByteLengthOffset = kBackingStoreOffset + kPointerSize;
10311 static const int kFlagOffset = kByteLengthOffset + kPointerSize;
10312 static const int kWeakNextOffset = kFlagOffset + kPointerSize;
10313 static const int kWeakFirstViewOffset = kWeakNextOffset + kPointerSize;
10314 static const int kSize = kWeakFirstViewOffset + kPointerSize;
10315
10316 static const int kSizeWithInternalFields =
10317 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
10318
10319 private:
10320 // Bit position in a flag
10321 static const int kIsExternalBit = 0;
10322 static const int kShouldBeFreed = 1;
10323
10324 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
10325 };
10326
10327
10328 class JSArrayBufferView: public JSObject {
10329 public:
10330 // [buffer]: ArrayBuffer that this typed array views.
10331 DECL_ACCESSORS(buffer, Object)
10332
10333 // [byte_length]: offset of typed array in bytes.
10334 DECL_ACCESSORS(byte_offset, Object)
10335
10336 // [byte_length]: length of typed array in bytes.
10337 DECL_ACCESSORS(byte_length, Object)
10338
10339 // [weak_next]: linked list of typed arrays over the same array buffer.
10340 DECL_ACCESSORS(weak_next, Object)
10341
10342 // Casting.
10343 static inline JSArrayBufferView* cast(Object* obj);
10344
10345 DECLARE_VERIFIER(JSArrayBufferView)
10346
10347 static const int kBufferOffset = JSObject::kHeaderSize;
10348 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10349 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
10350 static const int kWeakNextOffset = kByteLengthOffset + kPointerSize;
10351 static const int kViewSize = kWeakNextOffset + kPointerSize;
10352
10353 protected:
10354 void NeuterView();
10355
10356 private:
10357 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10358 };
10359
10360
10361 class JSTypedArray: public JSArrayBufferView {
10362 public:
10363 // [length]: length of typed array in elements.
10364 DECL_ACCESSORS(length, Object)
10365
10366 // Neutering. Only neuters this typed array.
10367 void Neuter();
10368
10369 // Casting.
10370 static inline JSTypedArray* cast(Object* obj);
10371
10372 ExternalArrayType type();
10373 size_t element_size();
10374
10375 Handle<JSArrayBuffer> GetBuffer();
10376
10377 // Dispatched behavior.
10378 DECLARE_PRINTER(JSTypedArray)
10379 DECLARE_VERIFIER(JSTypedArray)
10380
10381 static const int kLengthOffset = kViewSize + kPointerSize;
10382 static const int kSize = kLengthOffset + kPointerSize;
10383
10384 static const int kSizeWithInternalFields =
10385 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10386
10387 private:
10388 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10389 Handle<JSTypedArray> typed_array);
10390
10391 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10392 };
10393
10394
10395 class JSDataView: public JSArrayBufferView {
10396 public:
10397 // Only neuters this DataView
10398 void Neuter();
10399
10400 // Casting.
10401 static inline JSDataView* cast(Object* obj);
10402
10403 // Dispatched behavior.
10404 DECLARE_PRINTER(JSDataView)
10405 DECLARE_VERIFIER(JSDataView)
10406
10407 static const int kSize = kViewSize;
10408
10409 static const int kSizeWithInternalFields =
10410 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10411
10412 private:
10413 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10414 };
10415
10416
10417 // Foreign describes objects pointing from JavaScript to C structures.
10418 // Since they cannot contain references to JS HeapObjects they can be
10419 // placed in old_data_space.
10420 class Foreign: public HeapObject {
10421 public:
10422 // [address]: field containing the address.
10423 inline Address foreign_address();
10424 inline void set_foreign_address(Address value);
10425
10426 // Casting.
10427 static inline Foreign* cast(Object* obj);
10428
10429 // Dispatched behavior.
10430 inline void ForeignIterateBody(ObjectVisitor* v);
10431
10432 template<typename StaticVisitor>
10433 inline void ForeignIterateBody();
10434
10435 // Dispatched behavior.
10436 DECLARE_PRINTER(Foreign)
10437 DECLARE_VERIFIER(Foreign)
10438
10439 // Layout description.
10440
10441 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10442 static const int kSize = kForeignAddressOffset + kPointerSize;
10443
10444 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
10445
10446 private:
10447 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
10448 };
10449
10450
10451 // The JSArray describes JavaScript Arrays
10452 // Such an array can be in one of two modes:
10453 // - fast, backing storage is a FixedArray and length <= elements.length();
10454 // Please note: push and pop can be used to grow and shrink the array.
10455 // - slow, backing storage is a HashTable with numbers as keys.
10456 class JSArray: public JSObject {
10457 public:
10458 // [length]: The length property.
10459 DECL_ACCESSORS(length, Object)
10460
10461 // Overload the length setter to skip write barrier when the length
10462 // is set to a smi. This matches the set function on FixedArray.
10463 inline void set_length(Smi* length);
10464
10465 static void JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
10466 uint32_t index,
10467 Handle<Object> value);
10468
10469 static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
10470 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
10471 static MaybeHandle<Object> ReadOnlyLengthError(Handle<JSArray> array);
10472
10473 // Initialize the array with the given capacity. The function may
10474 // fail due to out-of-memory situations, but only if the requested
10475 // capacity is non-zero.
10476 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
10477
10478 // Initializes the array to a certain length.
10479 inline bool AllowsSetElementsLength();
10480 // Can cause GC.
10481 MUST_USE_RESULT static MaybeHandle<Object> SetElementsLength(
10482 Handle<JSArray> array,
10483 Handle<Object> length);
10484
10485 // Set the content of the array to the content of storage.
10486 static inline void SetContent(Handle<JSArray> array,
10487 Handle<FixedArrayBase> storage);
10488
10489 // Casting.
10490 static inline JSArray* cast(Object* obj);
10491
10492 // Ensures that the fixed array backing the JSArray has at
10493 // least the stated size.
10494 static inline void EnsureSize(Handle<JSArray> array,
10495 int minimum_size_of_backing_fixed_array);
10496
10497 // Expand the fixed array backing of a fast-case JSArray to at least
10498 // the requested size.
10499 static void Expand(Handle<JSArray> array,
10500 int minimum_size_of_backing_fixed_array);
10501
10502 // Dispatched behavior.
10503 DECLARE_PRINTER(JSArray)
10504 DECLARE_VERIFIER(JSArray)
10505
10506 // Number of element slots to pre-allocate for an empty array.
10507 static const int kPreallocatedArrayElements = 4;
10508
10509 // Layout description.
10510 static const int kLengthOffset = JSObject::kHeaderSize;
10511 static const int kSize = kLengthOffset + kPointerSize;
10512
10513 private:
10514 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10515 };
10516
10517
10518 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10519 Handle<Map> initial_map);
10520
10521
10522 // JSRegExpResult is just a JSArray with a specific initial map.
10523 // This initial map adds in-object properties for "index" and "input"
10524 // properties, as assigned by RegExp.prototype.exec, which allows
10525 // faster creation of RegExp exec results.
10526 // This class just holds constants used when creating the result.
10527 // After creation the result must be treated as a JSArray in all regards.
10528 class JSRegExpResult: public JSArray {
10529 public:
10530 // Offsets of object fields.
10531 static const int kIndexOffset = JSArray::kSize;
10532 static const int kInputOffset = kIndexOffset + kPointerSize;
10533 static const int kSize = kInputOffset + kPointerSize;
10534 // Indices of in-object properties.
10535 static const int kIndexIndex = 0;
10536 static const int kInputIndex = 1;
10537 private:
10538 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10539 };
10540
10541
10542 class AccessorInfo: public Struct {
10543 public:
10544 DECL_ACCESSORS(name, Object)
10545 DECL_ACCESSORS(flag, Smi)
10546 DECL_ACCESSORS(expected_receiver_type, Object)
10547
10548 inline bool all_can_read();
10549 inline void set_all_can_read(bool value);
10550
10551 inline bool all_can_write();
10552 inline void set_all_can_write(bool value);
10553
10554 inline PropertyAttributes property_attributes();
10555 inline void set_property_attributes(PropertyAttributes attributes);
10556
10557 // Checks whether the given receiver is compatible with this accessor.
10558 inline bool IsCompatibleReceiver(Object* receiver);
10559
10560 static inline AccessorInfo* cast(Object* obj);
10561
10562 // Dispatched behavior.
10563 DECLARE_VERIFIER(AccessorInfo)
10564
10565 // Append all descriptors to the array that are not already there.
10566 // Return number added.
10567 static int AppendUnique(Handle<Object> descriptors,
10568 Handle<FixedArray> array,
10569 int valid_descriptors);
10570
10571 static const int kNameOffset = HeapObject::kHeaderSize;
10572 static const int kFlagOffset = kNameOffset + kPointerSize;
10573 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
10574 static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
10575
10576 private:
10577 // Bit positions in flag.
10578 static const int kAllCanReadBit = 0;
10579 static const int kAllCanWriteBit = 1;
10580 class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
10581
10582 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
10583 };
10584
10585
10586 enum AccessorDescriptorType {
10587 kDescriptorBitmaskCompare,
10588 kDescriptorPointerCompare,
10589 kDescriptorPrimitiveValue,
10590 kDescriptorObjectDereference,
10591 kDescriptorPointerDereference,
10592 kDescriptorPointerShift,
10593 kDescriptorReturnObject
10594 };
10595
10596
10597 struct BitmaskCompareDescriptor {
10598 uint32_t bitmask;
10599 uint32_t compare_value;
10600 uint8_t size; // Must be in {1,2,4}.
10601 };
10602
10603
10604 struct PointerCompareDescriptor {
10605 void* compare_value;
10606 };
10607
10608
10609 struct PrimitiveValueDescriptor {
10610 v8::DeclaredAccessorDescriptorDataType data_type;
10611 uint8_t bool_offset; // Must be in [0,7], used for kDescriptorBoolType.
10612 };
10613
10614
10615 struct ObjectDerefenceDescriptor {
10616 uint8_t internal_field;
10617 };
10618
10619
10620 struct PointerShiftDescriptor {
10621 int16_t byte_offset;
10622 };
10623
10624
10625 struct DeclaredAccessorDescriptorData {
10626 AccessorDescriptorType type;
10627 union {
10628 struct BitmaskCompareDescriptor bitmask_compare_descriptor;
10629 struct PointerCompareDescriptor pointer_compare_descriptor;
10630 struct PrimitiveValueDescriptor primitive_value_descriptor;
10631 struct ObjectDerefenceDescriptor object_dereference_descriptor;
10632 struct PointerShiftDescriptor pointer_shift_descriptor;
10633 };
10634 };
10635
10636
10637 class DeclaredAccessorDescriptor;
10638
10639
10640 class DeclaredAccessorDescriptorIterator {
10641 public:
10642 explicit DeclaredAccessorDescriptorIterator(
10643 DeclaredAccessorDescriptor* descriptor);
10644 const DeclaredAccessorDescriptorData* Next();
Complete()10645 bool Complete() const { return length_ == offset_; }
10646 private:
10647 uint8_t* array_;
10648 const int length_;
10649 int offset_;
10650 DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptorIterator);
10651 };
10652
10653
10654 class DeclaredAccessorDescriptor: public Struct {
10655 public:
10656 DECL_ACCESSORS(serialized_data, ByteArray)
10657
10658 static inline DeclaredAccessorDescriptor* cast(Object* obj);
10659
10660 static Handle<DeclaredAccessorDescriptor> Create(
10661 Isolate* isolate,
10662 const DeclaredAccessorDescriptorData& data,
10663 Handle<DeclaredAccessorDescriptor> previous);
10664
10665 // Dispatched behavior.
10666 DECLARE_PRINTER(DeclaredAccessorDescriptor)
10667 DECLARE_VERIFIER(DeclaredAccessorDescriptor)
10668
10669 static const int kSerializedDataOffset = HeapObject::kHeaderSize;
10670 static const int kSize = kSerializedDataOffset + kPointerSize;
10671
10672 private:
10673 DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptor);
10674 };
10675
10676
10677 class DeclaredAccessorInfo: public AccessorInfo {
10678 public:
10679 DECL_ACCESSORS(descriptor, DeclaredAccessorDescriptor)
10680
10681 static inline DeclaredAccessorInfo* cast(Object* obj);
10682
10683 // Dispatched behavior.
10684 DECLARE_PRINTER(DeclaredAccessorInfo)
10685 DECLARE_VERIFIER(DeclaredAccessorInfo)
10686
10687 static const int kDescriptorOffset = AccessorInfo::kSize;
10688 static const int kSize = kDescriptorOffset + kPointerSize;
10689
10690 private:
10691 DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorInfo);
10692 };
10693
10694
10695 // An accessor must have a getter, but can have no setter.
10696 //
10697 // When setting a property, V8 searches accessors in prototypes.
10698 // If an accessor was found and it does not have a setter,
10699 // the request is ignored.
10700 //
10701 // If the accessor in the prototype has the READ_ONLY property attribute, then
10702 // a new value is added to the derived object when the property is set.
10703 // This shadows the accessor in the prototype.
10704 class ExecutableAccessorInfo: public AccessorInfo {
10705 public:
10706 DECL_ACCESSORS(getter, Object)
10707 DECL_ACCESSORS(setter, Object)
10708 DECL_ACCESSORS(data, Object)
10709
10710 static inline ExecutableAccessorInfo* cast(Object* obj);
10711
10712 // Dispatched behavior.
10713 DECLARE_PRINTER(ExecutableAccessorInfo)
10714 DECLARE_VERIFIER(ExecutableAccessorInfo)
10715
10716 static const int kGetterOffset = AccessorInfo::kSize;
10717 static const int kSetterOffset = kGetterOffset + kPointerSize;
10718 static const int kDataOffset = kSetterOffset + kPointerSize;
10719 static const int kSize = kDataOffset + kPointerSize;
10720
10721 inline void clear_setter();
10722
10723 private:
10724 DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
10725 };
10726
10727
10728 // Support for JavaScript accessors: A pair of a getter and a setter. Each
10729 // accessor can either be
10730 // * a pointer to a JavaScript function or proxy: a real accessor
10731 // * undefined: considered an accessor by the spec, too, strangely enough
10732 // * the hole: an accessor which has not been set
10733 // * a pointer to a map: a transition used to ensure map sharing
10734 // access_flags provides the ability to override access checks on access check
10735 // failure.
10736 class AccessorPair: public Struct {
10737 public:
10738 DECL_ACCESSORS(getter, Object)
10739 DECL_ACCESSORS(setter, Object)
10740 DECL_ACCESSORS(access_flags, Smi)
10741
10742 inline void set_access_flags(v8::AccessControl access_control);
10743 inline bool all_can_read();
10744 inline bool all_can_write();
10745
10746 static inline AccessorPair* cast(Object* obj);
10747
10748 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
10749
get(AccessorComponent component)10750 Object* get(AccessorComponent component) {
10751 return component == ACCESSOR_GETTER ? getter() : setter();
10752 }
10753
set(AccessorComponent component,Object * value)10754 void set(AccessorComponent component, Object* value) {
10755 if (component == ACCESSOR_GETTER) {
10756 set_getter(value);
10757 } else {
10758 set_setter(value);
10759 }
10760 }
10761
10762 // Note: Returns undefined instead in case of a hole.
10763 Object* GetComponent(AccessorComponent component);
10764
10765 // Set both components, skipping arguments which are a JavaScript null.
SetComponents(Object * getter,Object * setter)10766 void SetComponents(Object* getter, Object* setter) {
10767 if (!getter->IsNull()) set_getter(getter);
10768 if (!setter->IsNull()) set_setter(setter);
10769 }
10770
ContainsAccessor()10771 bool ContainsAccessor() {
10772 return IsJSAccessor(getter()) || IsJSAccessor(setter());
10773 }
10774
10775 // Dispatched behavior.
10776 DECLARE_PRINTER(AccessorPair)
10777 DECLARE_VERIFIER(AccessorPair)
10778
10779 static const int kGetterOffset = HeapObject::kHeaderSize;
10780 static const int kSetterOffset = kGetterOffset + kPointerSize;
10781 static const int kAccessFlagsOffset = kSetterOffset + kPointerSize;
10782 static const int kSize = kAccessFlagsOffset + kPointerSize;
10783
10784 private:
10785 static const int kAllCanReadBit = 0;
10786 static const int kAllCanWriteBit = 1;
10787
10788 // Strangely enough, in addition to functions and harmony proxies, the spec
10789 // requires us to consider undefined as a kind of accessor, too:
10790 // var obj = {};
10791 // Object.defineProperty(obj, "foo", {get: undefined});
10792 // assertTrue("foo" in obj);
IsJSAccessor(Object * obj)10793 bool IsJSAccessor(Object* obj) {
10794 return obj->IsSpecFunction() || obj->IsUndefined();
10795 }
10796
10797 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
10798 };
10799
10800
10801 class AccessCheckInfo: public Struct {
10802 public:
10803 DECL_ACCESSORS(named_callback, Object)
10804 DECL_ACCESSORS(indexed_callback, Object)
10805 DECL_ACCESSORS(data, Object)
10806
10807 static inline AccessCheckInfo* cast(Object* obj);
10808
10809 // Dispatched behavior.
10810 DECLARE_PRINTER(AccessCheckInfo)
10811 DECLARE_VERIFIER(AccessCheckInfo)
10812
10813 static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
10814 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
10815 static const int kDataOffset = kIndexedCallbackOffset + kPointerSize;
10816 static const int kSize = kDataOffset + kPointerSize;
10817
10818 private:
10819 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10820 };
10821
10822
10823 class InterceptorInfo: public Struct {
10824 public:
10825 DECL_ACCESSORS(getter, Object)
10826 DECL_ACCESSORS(setter, Object)
10827 DECL_ACCESSORS(query, Object)
10828 DECL_ACCESSORS(deleter, Object)
10829 DECL_ACCESSORS(enumerator, Object)
10830 DECL_ACCESSORS(data, Object)
10831
10832 static inline InterceptorInfo* cast(Object* obj);
10833
10834 // Dispatched behavior.
10835 DECLARE_PRINTER(InterceptorInfo)
10836 DECLARE_VERIFIER(InterceptorInfo)
10837
10838 static const int kGetterOffset = HeapObject::kHeaderSize;
10839 static const int kSetterOffset = kGetterOffset + kPointerSize;
10840 static const int kQueryOffset = kSetterOffset + kPointerSize;
10841 static const int kDeleterOffset = kQueryOffset + kPointerSize;
10842 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10843 static const int kDataOffset = kEnumeratorOffset + kPointerSize;
10844 static const int kSize = kDataOffset + kPointerSize;
10845
10846 private:
10847 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10848 };
10849
10850
10851 class CallHandlerInfo: public Struct {
10852 public:
10853 DECL_ACCESSORS(callback, Object)
10854 DECL_ACCESSORS(data, Object)
10855
10856 static inline CallHandlerInfo* cast(Object* obj);
10857
10858 // Dispatched behavior.
10859 DECLARE_PRINTER(CallHandlerInfo)
10860 DECLARE_VERIFIER(CallHandlerInfo)
10861
10862 static const int kCallbackOffset = HeapObject::kHeaderSize;
10863 static const int kDataOffset = kCallbackOffset + kPointerSize;
10864 static const int kSize = kDataOffset + kPointerSize;
10865
10866 private:
10867 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10868 };
10869
10870
10871 class TemplateInfo: public Struct {
10872 public:
10873 DECL_ACCESSORS(tag, Object)
10874 DECL_ACCESSORS(property_list, Object)
10875 DECL_ACCESSORS(property_accessors, Object)
10876
10877 DECLARE_VERIFIER(TemplateInfo)
10878
10879 static const int kTagOffset = HeapObject::kHeaderSize;
10880 static const int kPropertyListOffset = kTagOffset + kPointerSize;
10881 static const int kPropertyAccessorsOffset =
10882 kPropertyListOffset + kPointerSize;
10883 static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize;
10884
10885 private:
10886 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10887 };
10888
10889
10890 class FunctionTemplateInfo: public TemplateInfo {
10891 public:
10892 DECL_ACCESSORS(serial_number, Object)
10893 DECL_ACCESSORS(call_code, Object)
10894 DECL_ACCESSORS(prototype_template, Object)
10895 DECL_ACCESSORS(parent_template, Object)
10896 DECL_ACCESSORS(named_property_handler, Object)
10897 DECL_ACCESSORS(indexed_property_handler, Object)
10898 DECL_ACCESSORS(instance_template, Object)
10899 DECL_ACCESSORS(class_name, Object)
10900 DECL_ACCESSORS(signature, Object)
10901 DECL_ACCESSORS(instance_call_handler, Object)
10902 DECL_ACCESSORS(access_check_info, Object)
10903 DECL_ACCESSORS(flag, Smi)
10904
10905 inline int length();
10906 inline void set_length(int value);
10907
10908 // Following properties use flag bits.
10909 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10910 DECL_BOOLEAN_ACCESSORS(undetectable)
10911 // If the bit is set, object instances created by this function
10912 // requires access check.
10913 DECL_BOOLEAN_ACCESSORS(needs_access_check)
10914 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
10915 DECL_BOOLEAN_ACCESSORS(remove_prototype)
10916 DECL_BOOLEAN_ACCESSORS(do_not_cache)
10917
10918 static inline FunctionTemplateInfo* cast(Object* obj);
10919
10920 // Dispatched behavior.
10921 DECLARE_PRINTER(FunctionTemplateInfo)
10922 DECLARE_VERIFIER(FunctionTemplateInfo)
10923
10924 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
10925 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
10926 static const int kPrototypeTemplateOffset =
10927 kCallCodeOffset + kPointerSize;
10928 static const int kParentTemplateOffset =
10929 kPrototypeTemplateOffset + kPointerSize;
10930 static const int kNamedPropertyHandlerOffset =
10931 kParentTemplateOffset + kPointerSize;
10932 static const int kIndexedPropertyHandlerOffset =
10933 kNamedPropertyHandlerOffset + kPointerSize;
10934 static const int kInstanceTemplateOffset =
10935 kIndexedPropertyHandlerOffset + kPointerSize;
10936 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10937 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10938 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10939 static const int kAccessCheckInfoOffset =
10940 kInstanceCallHandlerOffset + kPointerSize;
10941 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
10942 static const int kLengthOffset = kFlagOffset + kPointerSize;
10943 static const int kSize = kLengthOffset + kPointerSize;
10944
10945 // Returns true if |object| is an instance of this function template.
10946 bool IsTemplateFor(Object* object);
10947 bool IsTemplateFor(Map* map);
10948
10949 private:
10950 // Bit position in the flag, from least significant bit position.
10951 static const int kHiddenPrototypeBit = 0;
10952 static const int kUndetectableBit = 1;
10953 static const int kNeedsAccessCheckBit = 2;
10954 static const int kReadOnlyPrototypeBit = 3;
10955 static const int kRemovePrototypeBit = 4;
10956 static const int kDoNotCacheBit = 5;
10957
10958 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10959 };
10960
10961
10962 class ObjectTemplateInfo: public TemplateInfo {
10963 public:
10964 DECL_ACCESSORS(constructor, Object)
10965 DECL_ACCESSORS(internal_field_count, Object)
10966
10967 static inline ObjectTemplateInfo* cast(Object* obj);
10968
10969 // Dispatched behavior.
10970 DECLARE_PRINTER(ObjectTemplateInfo)
10971 DECLARE_VERIFIER(ObjectTemplateInfo)
10972
10973 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10974 static const int kInternalFieldCountOffset =
10975 kConstructorOffset + kPointerSize;
10976 static const int kSize = kInternalFieldCountOffset + kPointerSize;
10977 };
10978
10979
10980 class SignatureInfo: public Struct {
10981 public:
10982 DECL_ACCESSORS(receiver, Object)
10983 DECL_ACCESSORS(args, Object)
10984
10985 static inline SignatureInfo* cast(Object* obj);
10986
10987 // Dispatched behavior.
10988 DECLARE_PRINTER(SignatureInfo)
10989 DECLARE_VERIFIER(SignatureInfo)
10990
10991 static const int kReceiverOffset = Struct::kHeaderSize;
10992 static const int kArgsOffset = kReceiverOffset + kPointerSize;
10993 static const int kSize = kArgsOffset + kPointerSize;
10994
10995 private:
10996 DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo);
10997 };
10998
10999
11000 class TypeSwitchInfo: public Struct {
11001 public:
11002 DECL_ACCESSORS(types, Object)
11003
11004 static inline TypeSwitchInfo* cast(Object* obj);
11005
11006 // Dispatched behavior.
11007 DECLARE_PRINTER(TypeSwitchInfo)
11008 DECLARE_VERIFIER(TypeSwitchInfo)
11009
11010 static const int kTypesOffset = Struct::kHeaderSize;
11011 static const int kSize = kTypesOffset + kPointerSize;
11012 };
11013
11014
11015 // The DebugInfo class holds additional information for a function being
11016 // debugged.
11017 class DebugInfo: public Struct {
11018 public:
11019 // The shared function info for the source being debugged.
11020 DECL_ACCESSORS(shared, SharedFunctionInfo)
11021 // Code object for the original code.
11022 DECL_ACCESSORS(original_code, Code)
11023 // Code object for the patched code. This code object is the code object
11024 // currently active for the function.
11025 DECL_ACCESSORS(code, Code)
11026 // Fixed array holding status information for each active break point.
11027 DECL_ACCESSORS(break_points, FixedArray)
11028
11029 // Check if there is a break point at a code position.
11030 bool HasBreakPoint(int code_position);
11031 // Get the break point info object for a code position.
11032 Object* GetBreakPointInfo(int code_position);
11033 // Clear a break point.
11034 static void ClearBreakPoint(Handle<DebugInfo> debug_info,
11035 int code_position,
11036 Handle<Object> break_point_object);
11037 // Set a break point.
11038 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
11039 int source_position, int statement_position,
11040 Handle<Object> break_point_object);
11041 // Get the break point objects for a code position.
11042 Object* GetBreakPointObjects(int code_position);
11043 // Find the break point info holding this break point object.
11044 static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info,
11045 Handle<Object> break_point_object);
11046 // Get the number of break points for this function.
11047 int GetBreakPointCount();
11048
11049 static inline DebugInfo* cast(Object* obj);
11050
11051 // Dispatched behavior.
11052 DECLARE_PRINTER(DebugInfo)
11053 DECLARE_VERIFIER(DebugInfo)
11054
11055 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
11056 static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
11057 static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize;
11058 static const int kActiveBreakPointsCountIndex =
11059 kPatchedCodeIndex + kPointerSize;
11060 static const int kBreakPointsStateIndex =
11061 kActiveBreakPointsCountIndex + kPointerSize;
11062 static const int kSize = kBreakPointsStateIndex + kPointerSize;
11063
11064 static const int kEstimatedNofBreakPointsInFunction = 16;
11065
11066 private:
11067 static const int kNoBreakPointInfo = -1;
11068
11069 // Lookup the index in the break_points array for a code position.
11070 int GetBreakPointInfoIndex(int code_position);
11071
11072 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
11073 };
11074
11075
11076 // The BreakPointInfo class holds information for break points set in a
11077 // function. The DebugInfo object holds a BreakPointInfo object for each code
11078 // position with one or more break points.
11079 class BreakPointInfo: public Struct {
11080 public:
11081 // The position in the code for the break point.
11082 DECL_ACCESSORS(code_position, Smi)
11083 // The position in the source for the break position.
11084 DECL_ACCESSORS(source_position, Smi)
11085 // The position in the source for the last statement before this break
11086 // position.
11087 DECL_ACCESSORS(statement_position, Smi)
11088 // List of related JavaScript break points.
11089 DECL_ACCESSORS(break_point_objects, Object)
11090
11091 // Removes a break point.
11092 static void ClearBreakPoint(Handle<BreakPointInfo> info,
11093 Handle<Object> break_point_object);
11094 // Set a break point.
11095 static void SetBreakPoint(Handle<BreakPointInfo> info,
11096 Handle<Object> break_point_object);
11097 // Check if break point info has this break point object.
11098 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
11099 Handle<Object> break_point_object);
11100 // Get the number of break points for this code position.
11101 int GetBreakPointCount();
11102
11103 static inline BreakPointInfo* cast(Object* obj);
11104
11105 // Dispatched behavior.
11106 DECLARE_PRINTER(BreakPointInfo)
11107 DECLARE_VERIFIER(BreakPointInfo)
11108
11109 static const int kCodePositionIndex = Struct::kHeaderSize;
11110 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
11111 static const int kStatementPositionIndex =
11112 kSourcePositionIndex + kPointerSize;
11113 static const int kBreakPointObjectsIndex =
11114 kStatementPositionIndex + kPointerSize;
11115 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
11116
11117 private:
11118 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
11119 };
11120
11121
11122 #undef DECL_BOOLEAN_ACCESSORS
11123 #undef DECL_ACCESSORS
11124 #undef DECLARE_VERIFIER
11125
11126 #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
11127 V(kStringTable, "string_table", "(Internalized strings)") \
11128 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
11129 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
11130 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
11131 V(kInternalizedString, "internalized_string", "(Internal string)") \
11132 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
11133 V(kTop, "top", "(Isolate)") \
11134 V(kRelocatable, "relocatable", "(Relocatable)") \
11135 V(kDebug, "debug", "(Debugger)") \
11136 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
11137 V(kHandleScope, "handlescope", "(Handle scope)") \
11138 V(kBuiltins, "builtins", "(Builtins)") \
11139 V(kGlobalHandles, "globalhandles", "(Global handles)") \
11140 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
11141 V(kThreadManager, "threadmanager", "(Thread manager)") \
11142 V(kExtensions, "Extensions", "(Extensions)")
11143
11144 class VisitorSynchronization : public AllStatic {
11145 public:
11146 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
11147 enum SyncTag {
11148 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
11149 kNumberOfSyncTags
11150 };
11151 #undef DECLARE_ENUM
11152
11153 static const char* const kTags[kNumberOfSyncTags];
11154 static const char* const kTagNames[kNumberOfSyncTags];
11155 };
11156
11157 // Abstract base class for visiting, and optionally modifying, the
11158 // pointers contained in Objects. Used in GC and serialization/deserialization.
11159 class ObjectVisitor BASE_EMBEDDED {
11160 public:
~ObjectVisitor()11161 virtual ~ObjectVisitor() {}
11162
11163 // Visits a contiguous arrays of pointers in the half-open range
11164 // [start, end). Any or all of the values may be modified on return.
11165 virtual void VisitPointers(Object** start, Object** end) = 0;
11166
11167 // Handy shorthand for visiting a single pointer.
VisitPointer(Object ** p)11168 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
11169
11170 // Visit weak next_code_link in Code object.
VisitNextCodeLink(Object ** p)11171 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
11172
11173 // To allow lazy clearing of inline caches the visitor has
11174 // a rich interface for iterating over Code objects..
11175
11176 // Visits a code target in the instruction stream.
11177 virtual void VisitCodeTarget(RelocInfo* rinfo);
11178
11179 // Visits a code entry in a JS function.
11180 virtual void VisitCodeEntry(Address entry_address);
11181
11182 // Visits a global property cell reference in the instruction stream.
11183 virtual void VisitCell(RelocInfo* rinfo);
11184
11185 // Visits a runtime entry in the instruction stream.
VisitRuntimeEntry(RelocInfo * rinfo)11186 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
11187
11188 // Visits the resource of an ASCII or two-byte string.
VisitExternalAsciiString(v8::String::ExternalAsciiStringResource ** resource)11189 virtual void VisitExternalAsciiString(
11190 v8::String::ExternalAsciiStringResource** resource) {}
VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)11191 virtual void VisitExternalTwoByteString(
11192 v8::String::ExternalStringResource** resource) {}
11193
11194 // Visits a debug call target in the instruction stream.
11195 virtual void VisitDebugTarget(RelocInfo* rinfo);
11196
11197 // Visits the byte sequence in a function's prologue that contains information
11198 // about the code's age.
11199 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
11200
11201 // Visit pointer embedded into a code object.
11202 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
11203
11204 // Visits an external reference embedded into a code object.
11205 virtual void VisitExternalReference(RelocInfo* rinfo);
11206
11207 // Visits an external reference. The value may be modified on return.
VisitExternalReference(Address * p)11208 virtual void VisitExternalReference(Address* p) {}
11209
11210 // Visits a handle that has an embedder-assigned class ID.
VisitEmbedderReference(Object ** p,uint16_t class_id)11211 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
11212
11213 // Intended for serialization/deserialization checking: insert, or
11214 // check for the presence of, a tag at this position in the stream.
11215 // Also used for marking up GC roots in heap snapshots.
Synchronize(VisitorSynchronization::SyncTag tag)11216 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
11217 };
11218
11219
11220 class StructBodyDescriptor : public
11221 FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
11222 public:
SizeOf(Map * map,HeapObject * object)11223 static inline int SizeOf(Map* map, HeapObject* object) {
11224 return map->instance_size();
11225 }
11226 };
11227
11228
11229 // BooleanBit is a helper class for setting and getting a bit in an
11230 // integer or Smi.
11231 class BooleanBit : public AllStatic {
11232 public:
get(Smi * smi,int bit_position)11233 static inline bool get(Smi* smi, int bit_position) {
11234 return get(smi->value(), bit_position);
11235 }
11236
get(int value,int bit_position)11237 static inline bool get(int value, int bit_position) {
11238 return (value & (1 << bit_position)) != 0;
11239 }
11240
set(Smi * smi,int bit_position,bool v)11241 static inline Smi* set(Smi* smi, int bit_position, bool v) {
11242 return Smi::FromInt(set(smi->value(), bit_position, v));
11243 }
11244
set(int value,int bit_position,bool v)11245 static inline int set(int value, int bit_position, bool v) {
11246 if (v) {
11247 value |= (1 << bit_position);
11248 } else {
11249 value &= ~(1 << bit_position);
11250 }
11251 return value;
11252 }
11253 };
11254
11255 } } // namespace v8::internal
11256
11257 #endif // V8_OBJECTS_H_
11258