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