blob: 18f45f3ba8a66516b1323dc51034d46e3e702753 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000056PropertyDetails PropertyDetails::AsDeleted() {
57 PropertyDetails d(DONT_ENUM, NORMAL);
58 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
59 return PropertyDetails(smi);
60}
61
62
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 ASSERT(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 }
68
69
70#define INT_ACCESSORS(holder, name, offset) \
71 int holder::name() { return READ_INT_FIELD(this, offset); } \
72 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
73
74
75#define ACCESSORS(holder, name, type, offset) \
76 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000077 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 }
81
82
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084#define SMI_ACCESSORS(holder, name, offset) \
85 int holder::name() { \
86 Object* value = READ_FIELD(this, offset); \
87 return Smi::cast(value)->value(); \
88 } \
89 void holder::set_##name(int value) { \
90 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
91 }
92
93
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000094#define BOOL_GETTER(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98
99
100#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104 void holder::set_##name(bool value) { \
105 set_##field(BooleanBit::set(field(), offset, value)); \
106 }
107
108
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000109bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
110 // There is a constraint on the object; check.
111 if (!this->IsJSObject()) return false;
112 // Fetch the constructor function of the object.
113 Object* cons_obj = JSObject::cast(this)->map()->constructor();
114 if (!cons_obj->IsJSFunction()) return false;
115 JSFunction* fun = JSFunction::cast(cons_obj);
116 // Iterate through the chain of inheriting function templates to
117 // see if the required one occurs.
118 for (Object* type = fun->shared()->function_data();
119 type->IsFunctionTemplateInfo();
120 type = FunctionTemplateInfo::cast(type)->parent_template()) {
121 if (type == expected) return true;
122 }
123 // Didn't find the required type in the inheritance chain.
124 return false;
125}
126
127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128bool Object::IsSmi() {
129 return HAS_SMI_TAG(this);
130}
131
132
133bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000134 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135}
136
137
138bool Object::IsHeapNumber() {
139 return Object::IsHeapObject()
140 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
141}
142
143
144bool Object::IsString() {
145 return Object::IsHeapObject()
146 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
147}
148
149
ager@chromium.org870a0b62008-11-04 11:43:05 +0000150bool Object::IsSymbol() {
151 if (!this->IsHeapObject()) return false;
152 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000153 // Because the symbol tag is non-zero and no non-string types have the
154 // symbol bit set we can test for symbols with a very simple test
155 // operation.
156 ASSERT(kSymbolTag != 0);
157 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
158 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159}
160
161
162bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000163 if (!this->IsHeapObject()) return false;
164 uint32_t type = HeapObject::cast(this)->map()->instance_type();
165 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
166 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167}
168
169
ager@chromium.org870a0b62008-11-04 11:43:05 +0000170bool Object::IsSeqString() {
171 if (!IsString()) return false;
172 return StringShape(String::cast(this)).IsSequential();
173}
174
175
176bool Object::IsSeqAsciiString() {
177 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000178 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000179 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180}
181
182
183bool Object::IsSeqTwoByteString() {
184 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000185 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000186 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187}
188
189
190bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191 if (!IsString()) return false;
192 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000198 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000199 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200}
201
202
203bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000204 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000205 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000206 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207}
208
209
ager@chromium.org870a0b62008-11-04 11:43:05 +0000210StringShape::StringShape(String* str)
211 : type_(str->map()->instance_type()) {
212 set_valid();
213 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217StringShape::StringShape(Map* map)
218 : type_(map->instance_type()) {
219 set_valid();
220 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221}
222
223
ager@chromium.org870a0b62008-11-04 11:43:05 +0000224StringShape::StringShape(InstanceType t)
225 : type_(static_cast<uint32_t>(t)) {
226 set_valid();
227 ASSERT((type_ & kIsNotStringMask) == kStringTag);
228}
229
230
231bool StringShape::IsSymbol() {
232 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000233 ASSERT(kSymbolTag != 0);
234 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235}
236
237
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238bool String::IsAsciiRepresentation() {
239 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240 if ((type & kStringRepresentationMask) == kConsStringTag &&
241 ConsString::cast(this)->second()->length() == 0) {
242 return ConsString::cast(this)->first()->IsAsciiRepresentation();
243 }
244 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245}
246
247
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248bool String::IsTwoByteRepresentation() {
249 uint32_t type = map()->instance_type();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000250 if ((type & kStringRepresentationMask) == kConsStringTag &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 ConsString::cast(this)->second()->length() == 0) {
252 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
253 }
254 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000255}
256
257
258bool StringShape::IsCons() {
259 return (type_ & kStringRepresentationMask) == kConsStringTag;
260}
261
262
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263bool StringShape::IsExternal() {
264 return (type_ & kStringRepresentationMask) == kExternalStringTag;
265}
266
267
268bool StringShape::IsSequential() {
269 return (type_ & kStringRepresentationMask) == kSeqStringTag;
270}
271
272
273StringRepresentationTag StringShape::representation_tag() {
274 uint32_t tag = (type_ & kStringRepresentationMask);
275 return static_cast<StringRepresentationTag>(tag);
276}
277
278
279uint32_t StringShape::full_representation_tag() {
280 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
281}
282
283
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000284STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
285 Internals::kFullStringRepresentationMask);
286
287
ager@chromium.org870a0b62008-11-04 11:43:05 +0000288bool StringShape::IsSequentialAscii() {
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
290}
291
292
293bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
298bool StringShape::IsExternalAscii() {
299 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305}
306
307
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000308STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
309 Internals::kExternalTwoByteRepresentationTag);
310
311
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312uc32 FlatStringReader::Get(int index) {
313 ASSERT(0 <= index && index <= length_);
314 if (is_ascii_) {
315 return static_cast<const byte*>(start_)[index];
316 } else {
317 return static_cast<const uc16*>(start_)[index];
318 }
319}
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322bool Object::IsNumber() {
323 return IsSmi() || IsHeapNumber();
324}
325
326
327bool Object::IsByteArray() {
328 return Object::IsHeapObject()
329 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
330}
331
332
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000333bool Object::IsPixelArray() {
334 return Object::IsHeapObject() &&
335 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
336}
337
338
ager@chromium.org3811b432009-10-28 14:53:37 +0000339bool Object::IsExternalArray() {
340 if (!Object::IsHeapObject())
341 return false;
342 InstanceType instance_type =
343 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000344 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
345 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000346}
347
348
349bool Object::IsExternalByteArray() {
350 return Object::IsHeapObject() &&
351 HeapObject::cast(this)->map()->instance_type() ==
352 EXTERNAL_BYTE_ARRAY_TYPE;
353}
354
355
356bool Object::IsExternalUnsignedByteArray() {
357 return Object::IsHeapObject() &&
358 HeapObject::cast(this)->map()->instance_type() ==
359 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
360}
361
362
363bool Object::IsExternalShortArray() {
364 return Object::IsHeapObject() &&
365 HeapObject::cast(this)->map()->instance_type() ==
366 EXTERNAL_SHORT_ARRAY_TYPE;
367}
368
369
370bool Object::IsExternalUnsignedShortArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalIntArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_INT_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalUnsignedIntArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalFloatArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_FLOAT_ARRAY_TYPE;
395}
396
397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398bool Object::IsFailure() {
399 return HAS_FAILURE_TAG(this);
400}
401
402
403bool Object::IsRetryAfterGC() {
404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
ager@chromium.org7c537e22008-10-16 08:43:32 +0000409bool Object::IsOutOfMemoryFailure() {
410 return HAS_FAILURE_TAG(this)
411 && Failure::cast(this)->IsOutOfMemoryException();
412}
413
414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415bool Object::IsException() {
416 return this == Failure::Exception();
417}
418
419
420bool Object::IsJSObject() {
421 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000422 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423}
424
425
ager@chromium.org32912102009-01-16 10:38:43 +0000426bool Object::IsJSContextExtensionObject() {
427 return IsHeapObject()
428 && (HeapObject::cast(this)->map()->instance_type() ==
429 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
430}
431
432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433bool Object::IsMap() {
434 return Object::IsHeapObject()
435 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
436}
437
438
439bool Object::IsFixedArray() {
440 return Object::IsHeapObject()
441 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
442}
443
444
445bool Object::IsDescriptorArray() {
446 return IsFixedArray();
447}
448
449
450bool Object::IsContext() {
451 return Object::IsHeapObject()
452 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000453 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 HeapObject::cast(this)->map() == Heap::global_context_map());
455}
456
457
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000458bool Object::IsCatchContext() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::catch_context_map();
461}
462
463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464bool Object::IsGlobalContext() {
465 return Object::IsHeapObject()
466 && HeapObject::cast(this)->map() == Heap::global_context_map();
467}
468
469
470bool Object::IsJSFunction() {
471 return Object::IsHeapObject()
472 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
473}
474
475
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000476template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 return obj->IsJSFunction();
478}
479
480
481bool Object::IsCode() {
482 return Object::IsHeapObject()
483 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
484}
485
486
487bool Object::IsOddball() {
488 return Object::IsHeapObject()
489 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
490}
491
492
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000493bool Object::IsJSGlobalPropertyCell() {
494 return Object::IsHeapObject()
495 && HeapObject::cast(this)->map()->instance_type()
496 == JS_GLOBAL_PROPERTY_CELL_TYPE;
497}
498
499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500bool Object::IsSharedFunctionInfo() {
501 return Object::IsHeapObject() &&
502 (HeapObject::cast(this)->map()->instance_type() ==
503 SHARED_FUNCTION_INFO_TYPE);
504}
505
506
507bool Object::IsJSValue() {
508 return Object::IsHeapObject()
509 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
510}
511
512
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000513bool Object::IsStringWrapper() {
514 return IsJSValue() && JSValue::cast(this)->value()->IsString();
515}
516
517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518bool Object::IsProxy() {
519 return Object::IsHeapObject()
520 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
521}
522
523
524bool Object::IsBoolean() {
525 return IsTrue() || IsFalse();
526}
527
528
529bool Object::IsJSArray() {
530 return Object::IsHeapObject()
531 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
532}
533
534
ager@chromium.org236ad962008-09-25 09:45:57 +0000535bool Object::IsJSRegExp() {
536 return Object::IsHeapObject()
537 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
538}
539
540
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000541template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 return obj->IsJSArray();
543}
544
545
546bool Object::IsHashTable() {
547 return Object::IsHeapObject()
548 && HeapObject::cast(this)->map() == Heap::hash_table_map();
549}
550
551
552bool Object::IsDictionary() {
553 return IsHashTable() && this != Heap::symbol_table();
554}
555
556
557bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000558 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000562bool Object::IsCompilationCacheTable() {
563 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000564}
565
566
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000567bool Object::IsCodeCacheHashTable() {
568 return IsHashTable();
569}
570
571
ager@chromium.org236ad962008-09-25 09:45:57 +0000572bool Object::IsMapCache() {
573 return IsHashTable();
574}
575
576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577bool Object::IsPrimitive() {
578 return IsOddball() || IsNumber() || IsString();
579}
580
581
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000582bool Object::IsJSGlobalProxy() {
583 bool result = IsHeapObject() &&
584 (HeapObject::cast(this)->map()->instance_type() ==
585 JS_GLOBAL_PROXY_TYPE);
586 ASSERT(!result || IsAccessCheckNeeded());
587 return result;
588}
589
590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000592 if (!IsHeapObject()) return false;
593
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000594 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000595 return type == JS_GLOBAL_OBJECT_TYPE ||
596 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000597}
598
599
600bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601 return IsHeapObject() &&
602 (HeapObject::cast(this)->map()->instance_type() ==
603 JS_GLOBAL_OBJECT_TYPE);
604}
605
606
607bool Object::IsJSBuiltinsObject() {
608 return IsHeapObject() &&
609 (HeapObject::cast(this)->map()->instance_type() ==
610 JS_BUILTINS_OBJECT_TYPE);
611}
612
613
614bool Object::IsUndetectableObject() {
615 return IsHeapObject()
616 && HeapObject::cast(this)->map()->is_undetectable();
617}
618
619
620bool Object::IsAccessCheckNeeded() {
621 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000622 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
626bool Object::IsStruct() {
627 if (!IsHeapObject()) return false;
628 switch (HeapObject::cast(this)->map()->instance_type()) {
629#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
630 STRUCT_LIST(MAKE_STRUCT_CASE)
631#undef MAKE_STRUCT_CASE
632 default: return false;
633 }
634}
635
636
637#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
638 bool Object::Is##Name() { \
639 return Object::IsHeapObject() \
640 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
641 }
642 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
643#undef MAKE_STRUCT_PREDICATE
644
645
646bool Object::IsUndefined() {
647 return this == Heap::undefined_value();
648}
649
650
651bool Object::IsTheHole() {
652 return this == Heap::the_hole_value();
653}
654
655
656bool Object::IsNull() {
657 return this == Heap::null_value();
658}
659
660
661bool Object::IsTrue() {
662 return this == Heap::true_value();
663}
664
665
666bool Object::IsFalse() {
667 return this == Heap::false_value();
668}
669
670
671double Object::Number() {
672 ASSERT(IsNumber());
673 return IsSmi()
674 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
675 : reinterpret_cast<HeapNumber*>(this)->value();
676}
677
678
679
680Object* Object::ToSmi() {
681 if (IsSmi()) return this;
682 if (IsHeapNumber()) {
683 double value = HeapNumber::cast(this)->value();
684 int int_value = FastD2I(value);
685 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
686 return Smi::FromInt(int_value);
687 }
688 }
689 return Failure::Exception();
690}
691
692
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000693bool Object::HasSpecificClassOf(String* name) {
694 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698Object* Object::GetElement(uint32_t index) {
699 return GetElementWithReceiver(this, index);
700}
701
702
703Object* Object::GetProperty(String* key) {
704 PropertyAttributes attributes;
705 return GetPropertyWithReceiver(this, key, &attributes);
706}
707
708
709Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
710 return GetPropertyWithReceiver(this, key, attributes);
711}
712
713
714#define FIELD_ADDR(p, offset) \
715 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
716
717#define READ_FIELD(p, offset) \
718 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
719
720#define WRITE_FIELD(p, offset, value) \
721 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
722
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724#define WRITE_BARRIER(object, offset) \
725 Heap::RecordWrite(object->address(), offset);
726
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000727// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728// write due to the assert validating the written value.
729#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
730 if (mode == UPDATE_WRITE_BARRIER) { \
731 Heap::RecordWrite(object->address(), offset); \
732 } else { \
733 ASSERT(mode == SKIP_WRITE_BARRIER); \
734 ASSERT(Heap::InNewSpace(object) || \
735 !Heap::InNewSpace(READ_FIELD(object, offset))); \
736 }
737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738#define READ_DOUBLE_FIELD(p, offset) \
739 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
740
741#define WRITE_DOUBLE_FIELD(p, offset, value) \
742 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
743
744#define READ_INT_FIELD(p, offset) \
745 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
746
747#define WRITE_INT_FIELD(p, offset, value) \
748 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
749
ager@chromium.org3e875802009-06-29 08:26:34 +0000750#define READ_INTPTR_FIELD(p, offset) \
751 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
752
753#define WRITE_INTPTR_FIELD(p, offset, value) \
754 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
755
ager@chromium.org7c537e22008-10-16 08:43:32 +0000756#define READ_UINT32_FIELD(p, offset) \
757 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
758
759#define WRITE_UINT32_FIELD(p, offset, value) \
760 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
761
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000762#define READ_SHORT_FIELD(p, offset) \
763 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
764
765#define WRITE_SHORT_FIELD(p, offset, value) \
766 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
767
768#define READ_BYTE_FIELD(p, offset) \
769 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
770
771#define WRITE_BYTE_FIELD(p, offset, value) \
772 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
773
774
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000775Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
776 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000781 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785Smi* Smi::FromInt(int value) {
786 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000787 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000788 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000789 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000790 return reinterpret_cast<Smi*>(tagged_value);
791}
792
793
794Smi* Smi::FromIntptr(intptr_t value) {
795 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000796 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
797 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000798}
799
800
801Failure::Type Failure::type() const {
802 return static_cast<Type>(value() & kFailureTypeTagMask);
803}
804
805
806bool Failure::IsInternalError() const {
807 return type() == INTERNAL_ERROR;
808}
809
810
811bool Failure::IsOutOfMemoryException() const {
812 return type() == OUT_OF_MEMORY_EXCEPTION;
813}
814
815
816int Failure::requested() const {
817 const int kShiftBits =
818 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
819 STATIC_ASSERT(kShiftBits >= 0);
820 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000821 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822}
823
824
825AllocationSpace Failure::allocation_space() const {
826 ASSERT_EQ(RETRY_AFTER_GC, type());
827 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
828 & kSpaceTagMask);
829}
830
831
832Failure* Failure::InternalError() {
833 return Construct(INTERNAL_ERROR);
834}
835
836
837Failure* Failure::Exception() {
838 return Construct(EXCEPTION);
839}
840
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842Failure* Failure::OutOfMemoryException() {
843 return Construct(OUT_OF_MEMORY_EXCEPTION);
844}
845
846
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000847intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000848 return static_cast<intptr_t>(
849 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850}
851
852
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000853Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000854 // Assert that the space encoding fits in the three bytes allotted for it.
855 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000856 uintptr_t requested =
857 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
858 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000859 if (((requested << tag_bits) >> tag_bits) != requested) {
860 // No room for entire requested size in the bits. Round down to
861 // maximally representable size.
862 requested = static_cast<intptr_t>(
863 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
864 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000865 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000866 return Construct(RETRY_AFTER_GC, value);
867}
868
869
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000870Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000871 uintptr_t info =
872 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000873 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875}
876
877
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000878bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879#ifdef DEBUG
880 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
881#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000882
883#ifdef V8_TARGET_ARCH_X64
884 // To be representable as a long smi, the value must be a 32-bit integer.
885 bool result = (value == static_cast<int32_t>(value));
886#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887 // To be representable as an tagged small integer, the two
888 // most-significant bits of 'value' must be either 00 or 11 due to
889 // sign-extension. To check this we add 01 to the two
890 // most-significant bits, and check if the most-significant bit is 0
891 //
892 // CAUTION: The original code below:
893 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
894 // may lead to incorrect results according to the C language spec, and
895 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
896 // compiler may produce undefined results in case of signed integer
897 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000899#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000900 ASSERT(result == in_range);
901 return result;
902}
903
904
kasper.lund7276f142008-07-30 08:49:36 +0000905MapWord MapWord::FromMap(Map* map) {
906 return MapWord(reinterpret_cast<uintptr_t>(map));
907}
908
909
910Map* MapWord::ToMap() {
911 return reinterpret_cast<Map*>(value_);
912}
913
914
915bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000917}
918
919
920MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000921 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
922 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000923}
924
925
926HeapObject* MapWord::ToForwardingAddress() {
927 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000928 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000929}
930
931
932bool MapWord::IsMarked() {
933 return (value_ & kMarkingMask) == 0;
934}
935
936
937void MapWord::SetMark() {
938 value_ &= ~kMarkingMask;
939}
940
941
942void MapWord::ClearMark() {
943 value_ |= kMarkingMask;
944}
945
946
947bool MapWord::IsOverflowed() {
948 return (value_ & kOverflowMask) != 0;
949}
950
951
952void MapWord::SetOverflow() {
953 value_ |= kOverflowMask;
954}
955
956
957void MapWord::ClearOverflow() {
958 value_ &= ~kOverflowMask;
959}
960
961
962MapWord MapWord::EncodeAddress(Address map_address, int offset) {
963 // Offset is the distance in live bytes from the first live object in the
964 // same page. The offset between two objects in the same page should not
965 // exceed the object area size of a page.
966 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
967
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000968 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000969 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
970
971 Page* map_page = Page::FromAddress(map_address);
972 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
973
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000974 uintptr_t map_page_offset =
975 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000976
977 uintptr_t encoding =
978 (compact_offset << kForwardingOffsetShift) |
979 (map_page_offset << kMapPageOffsetShift) |
980 (map_page->mc_page_index << kMapPageIndexShift);
981 return MapWord(encoding);
982}
983
984
985Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000986 int map_page_index =
987 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +0000988 ASSERT_MAP_PAGE_INDEX(map_page_index);
989
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000990 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000991 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
992 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +0000993
994 return (map_space->PageAddress(map_page_index) + map_page_offset);
995}
996
997
998int MapWord::DecodeOffset() {
999 // The offset field is represented in the kForwardingOffsetBits
1000 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001001 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1002 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1003 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001004}
1005
1006
1007MapWord MapWord::FromEncodedAddress(Address address) {
1008 return MapWord(reinterpret_cast<uintptr_t>(address));
1009}
1010
1011
1012Address MapWord::ToEncodedAddress() {
1013 return reinterpret_cast<Address>(value_);
1014}
1015
1016
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001017#ifdef DEBUG
1018void HeapObject::VerifyObjectField(int offset) {
1019 VerifyPointer(READ_FIELD(this, offset));
1020}
1021#endif
1022
1023
1024Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001025 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026}
1027
1028
1029void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001030 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001031}
1032
1033
kasper.lund7276f142008-07-30 08:49:36 +00001034MapWord HeapObject::map_word() {
1035 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1036}
1037
1038
1039void HeapObject::set_map_word(MapWord map_word) {
1040 // WRITE_FIELD does not update the remembered set, but there is no need
1041 // here.
1042 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1043}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044
1045
1046HeapObject* HeapObject::FromAddress(Address address) {
1047 ASSERT_TAG_ALIGNED(address);
1048 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1049}
1050
1051
1052Address HeapObject::address() {
1053 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1054}
1055
1056
1057int HeapObject::Size() {
1058 return SizeFromMap(map());
1059}
1060
1061
1062void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1063 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1064 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1065}
1066
1067
1068void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1069 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1070}
1071
1072
kasper.lund7276f142008-07-30 08:49:36 +00001073bool HeapObject::IsMarked() {
1074 return map_word().IsMarked();
1075}
1076
1077
1078void HeapObject::SetMark() {
1079 ASSERT(!IsMarked());
1080 MapWord first_word = map_word();
1081 first_word.SetMark();
1082 set_map_word(first_word);
1083}
1084
1085
1086void HeapObject::ClearMark() {
1087 ASSERT(IsMarked());
1088 MapWord first_word = map_word();
1089 first_word.ClearMark();
1090 set_map_word(first_word);
1091}
1092
1093
1094bool HeapObject::IsOverflowed() {
1095 return map_word().IsOverflowed();
1096}
1097
1098
1099void HeapObject::SetOverflow() {
1100 MapWord first_word = map_word();
1101 first_word.SetOverflow();
1102 set_map_word(first_word);
1103}
1104
1105
1106void HeapObject::ClearOverflow() {
1107 ASSERT(IsOverflowed());
1108 MapWord first_word = map_word();
1109 first_word.ClearOverflow();
1110 set_map_word(first_word);
1111}
1112
1113
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114double HeapNumber::value() {
1115 return READ_DOUBLE_FIELD(this, kValueOffset);
1116}
1117
1118
1119void HeapNumber::set_value(double value) {
1120 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1121}
1122
1123
1124ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001125
1126
1127Array* JSObject::elements() {
1128 Object* array = READ_FIELD(this, kElementsOffset);
1129 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001130 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1131 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001132 return reinterpret_cast<Array*>(array);
1133}
1134
1135
1136void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1137 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001138 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1139 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001140 WRITE_FIELD(this, kElementsOffset, value);
1141 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1142}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001143
1144
1145void JSObject::initialize_properties() {
1146 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1147 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1148}
1149
1150
1151void JSObject::initialize_elements() {
1152 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1153 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1154}
1155
1156
1157ACCESSORS(Oddball, to_string, String, kToStringOffset)
1158ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1159
1160
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001161Object* JSGlobalPropertyCell::value() {
1162 return READ_FIELD(this, kValueOffset);
1163}
1164
1165
1166void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1167 // The write barrier is not used for global property cells.
1168 ASSERT(!val->IsJSGlobalPropertyCell());
1169 WRITE_FIELD(this, kValueOffset, val);
1170}
1171
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001172
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001173int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001174 InstanceType type = map()->instance_type();
1175 // Check for the most common kind of JavaScript object before
1176 // falling into the generic switch. This speeds up the internal
1177 // field operations considerably on average.
1178 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1179 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001180 case JS_GLOBAL_PROXY_TYPE:
1181 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001182 case JS_GLOBAL_OBJECT_TYPE:
1183 return JSGlobalObject::kSize;
1184 case JS_BUILTINS_OBJECT_TYPE:
1185 return JSBuiltinsObject::kSize;
1186 case JS_FUNCTION_TYPE:
1187 return JSFunction::kSize;
1188 case JS_VALUE_TYPE:
1189 return JSValue::kSize;
1190 case JS_ARRAY_TYPE:
1191 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001192 case JS_REGEXP_TYPE:
1193 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001194 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195 return JSObject::kHeaderSize;
1196 default:
1197 UNREACHABLE();
1198 return 0;
1199 }
1200}
1201
1202
1203int JSObject::GetInternalFieldCount() {
1204 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001205 // Make sure to adjust for the number of in-object properties. These
1206 // properties do contribute to the size, but are not internal fields.
1207 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1208 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001209}
1210
1211
1212Object* JSObject::GetInternalField(int index) {
1213 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001214 // Internal objects do follow immediately after the header, whereas in-object
1215 // properties are at the end of the object. Therefore there is no need
1216 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1218}
1219
1220
1221void JSObject::SetInternalField(int index, Object* value) {
1222 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001223 // Internal objects do follow immediately after the header, whereas in-object
1224 // properties are at the end of the object. Therefore there is no need
1225 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001226 int offset = GetHeaderSize() + (kPointerSize * index);
1227 WRITE_FIELD(this, offset, value);
1228 WRITE_BARRIER(this, offset);
1229}
1230
1231
ager@chromium.org7c537e22008-10-16 08:43:32 +00001232// Access fast-case object properties at index. The use of these routines
1233// is needed to correctly distinguish between properties stored in-object and
1234// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001235Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001236 // Adjust for the number of properties stored in the object.
1237 index -= map()->inobject_properties();
1238 if (index < 0) {
1239 int offset = map()->instance_size() + (index * kPointerSize);
1240 return READ_FIELD(this, offset);
1241 } else {
1242 ASSERT(index < properties()->length());
1243 return properties()->get(index);
1244 }
1245}
1246
1247
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001248Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001249 // Adjust for the number of properties stored in the object.
1250 index -= map()->inobject_properties();
1251 if (index < 0) {
1252 int offset = map()->instance_size() + (index * kPointerSize);
1253 WRITE_FIELD(this, offset, value);
1254 WRITE_BARRIER(this, offset);
1255 } else {
1256 ASSERT(index < properties()->length());
1257 properties()->set(index, value);
1258 }
1259 return value;
1260}
1261
1262
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001263Object* JSObject::InObjectPropertyAt(int index) {
1264 // Adjust for the number of properties stored in the object.
1265 index -= map()->inobject_properties();
1266 ASSERT(index < 0);
1267 int offset = map()->instance_size() + (index * kPointerSize);
1268 return READ_FIELD(this, offset);
1269}
1270
1271
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001272Object* JSObject::InObjectPropertyAtPut(int index,
1273 Object* value,
1274 WriteBarrierMode mode) {
1275 // Adjust for the number of properties stored in the object.
1276 index -= map()->inobject_properties();
1277 ASSERT(index < 0);
1278 int offset = map()->instance_size() + (index * kPointerSize);
1279 WRITE_FIELD(this, offset, value);
1280 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1281 return value;
1282}
1283
1284
1285
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001286void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001287 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001288 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001289 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001290 }
1291}
1292
1293
1294void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001295 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001296 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001297 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001298 }
1299}
1300
1301
1302bool JSObject::HasFastProperties() {
1303 return !properties()->IsDictionary();
1304}
1305
1306
1307bool Array::IndexFromObject(Object* object, uint32_t* index) {
1308 if (object->IsSmi()) {
1309 int value = Smi::cast(object)->value();
1310 if (value < 0) return false;
1311 *index = value;
1312 return true;
1313 }
1314 if (object->IsHeapNumber()) {
1315 double value = HeapNumber::cast(object)->value();
1316 uint32_t uint_value = static_cast<uint32_t>(value);
1317 if (value == static_cast<double>(uint_value)) {
1318 *index = uint_value;
1319 return true;
1320 }
1321 }
1322 return false;
1323}
1324
1325
1326bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1327 if (!this->IsJSValue()) return false;
1328
1329 JSValue* js_value = JSValue::cast(this);
1330 if (!js_value->value()->IsString()) return false;
1331
1332 String* str = String::cast(js_value->value());
1333 if (index >= (uint32_t)str->length()) return false;
1334
1335 return true;
1336}
1337
1338
1339Object* FixedArray::get(int index) {
1340 ASSERT(index >= 0 && index < this->length());
1341 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1342}
1343
1344
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001345void FixedArray::set(int index, Smi* value) {
1346 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1347 int offset = kHeaderSize + index * kPointerSize;
1348 WRITE_FIELD(this, offset, value);
1349}
1350
1351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001352void FixedArray::set(int index, Object* value) {
1353 ASSERT(index >= 0 && index < this->length());
1354 int offset = kHeaderSize + index * kPointerSize;
1355 WRITE_FIELD(this, offset, value);
1356 WRITE_BARRIER(this, offset);
1357}
1358
1359
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001360WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1362 return UPDATE_WRITE_BARRIER;
1363}
1364
1365
1366void FixedArray::set(int index,
1367 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001368 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001369 ASSERT(index >= 0 && index < this->length());
1370 int offset = kHeaderSize + index * kPointerSize;
1371 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001372 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373}
1374
1375
1376void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1377 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001378 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1380}
1381
1382
1383void FixedArray::set_undefined(int index) {
1384 ASSERT(index >= 0 && index < this->length());
1385 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1386 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1387 Heap::undefined_value());
1388}
1389
1390
ager@chromium.org236ad962008-09-25 09:45:57 +00001391void FixedArray::set_null(int index) {
1392 ASSERT(index >= 0 && index < this->length());
1393 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1394 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1395}
1396
1397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398void FixedArray::set_the_hole(int index) {
1399 ASSERT(index >= 0 && index < this->length());
1400 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1401 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1402}
1403
1404
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001405Object** FixedArray::data_start() {
1406 return HeapObject::RawField(this, kHeaderSize);
1407}
1408
1409
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001410bool DescriptorArray::IsEmpty() {
1411 ASSERT(this == Heap::empty_descriptor_array() ||
1412 this->length() > 2);
1413 return this == Heap::empty_descriptor_array();
1414}
1415
1416
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1418 Object* tmp = array->get(first);
1419 fast_set(array, first, array->get(second));
1420 fast_set(array, second, tmp);
1421}
1422
1423
1424int DescriptorArray::Search(String* name) {
1425 SLOW_ASSERT(IsSortedNoDuplicates());
1426
1427 // Check for empty descriptor array.
1428 int nof = number_of_descriptors();
1429 if (nof == 0) return kNotFound;
1430
1431 // Fast case: do linear search for small arrays.
1432 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001433 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001434 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 }
1436
1437 // Slow case: perform binary search.
1438 return BinarySearch(name, 0, nof - 1);
1439}
1440
1441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442String* DescriptorArray::GetKey(int descriptor_number) {
1443 ASSERT(descriptor_number < number_of_descriptors());
1444 return String::cast(get(ToKeyIndex(descriptor_number)));
1445}
1446
1447
1448Object* DescriptorArray::GetValue(int descriptor_number) {
1449 ASSERT(descriptor_number < number_of_descriptors());
1450 return GetContentArray()->get(ToValueIndex(descriptor_number));
1451}
1452
1453
1454Smi* DescriptorArray::GetDetails(int descriptor_number) {
1455 ASSERT(descriptor_number < number_of_descriptors());
1456 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1457}
1458
1459
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001460PropertyType DescriptorArray::GetType(int descriptor_number) {
1461 ASSERT(descriptor_number < number_of_descriptors());
1462 return PropertyDetails(GetDetails(descriptor_number)).type();
1463}
1464
1465
1466int DescriptorArray::GetFieldIndex(int descriptor_number) {
1467 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1468}
1469
1470
1471JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1472 return JSFunction::cast(GetValue(descriptor_number));
1473}
1474
1475
1476Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1477 ASSERT(GetType(descriptor_number) == CALLBACKS);
1478 return GetValue(descriptor_number);
1479}
1480
1481
1482AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1483 ASSERT(GetType(descriptor_number) == CALLBACKS);
1484 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1485 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1486}
1487
1488
1489bool DescriptorArray::IsProperty(int descriptor_number) {
1490 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1491}
1492
1493
1494bool DescriptorArray::IsTransition(int descriptor_number) {
1495 PropertyType t = GetType(descriptor_number);
1496 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1497}
1498
1499
1500bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1501 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1502}
1503
1504
1505bool DescriptorArray::IsDontEnum(int descriptor_number) {
1506 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1507}
1508
1509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1511 desc->Init(GetKey(descriptor_number),
1512 GetValue(descriptor_number),
1513 GetDetails(descriptor_number));
1514}
1515
1516
1517void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1518 // Range check.
1519 ASSERT(descriptor_number < number_of_descriptors());
1520
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001521 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1523 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1524
1525 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1526 FixedArray* content_array = GetContentArray();
1527 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1528 fast_set(content_array, ToDetailsIndex(descriptor_number),
1529 desc->GetDetails().AsSmi());
1530}
1531
1532
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001533void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1534 Descriptor desc;
1535 src->Get(src_index, &desc);
1536 Set(index, &desc);
1537}
1538
1539
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540void DescriptorArray::Swap(int first, int second) {
1541 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1542 FixedArray* content_array = GetContentArray();
1543 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1544 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1545}
1546
1547
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001548bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001549 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550 if (!max_index_object->IsSmi()) return false;
1551 return 0 !=
1552 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1553}
1554
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001555uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001557 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 if (!max_index_object->IsSmi()) return 0;
1559 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1560 return value >> kRequiresSlowElementsTagSize;
1561}
1562
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001563void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001564 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001565}
1566
1567
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001568// ------------------------------------
1569// Cast operations
1570
1571
1572CAST_ACCESSOR(FixedArray)
1573CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001574CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001575CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001576CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001577CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578CAST_ACCESSOR(String)
1579CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001580CAST_ACCESSOR(SeqAsciiString)
1581CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001582CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001583CAST_ACCESSOR(ExternalString)
1584CAST_ACCESSOR(ExternalAsciiString)
1585CAST_ACCESSOR(ExternalTwoByteString)
1586CAST_ACCESSOR(JSObject)
1587CAST_ACCESSOR(Smi)
1588CAST_ACCESSOR(Failure)
1589CAST_ACCESSOR(HeapObject)
1590CAST_ACCESSOR(HeapNumber)
1591CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001592CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593CAST_ACCESSOR(SharedFunctionInfo)
1594CAST_ACCESSOR(Map)
1595CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001596CAST_ACCESSOR(GlobalObject)
1597CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001598CAST_ACCESSOR(JSGlobalObject)
1599CAST_ACCESSOR(JSBuiltinsObject)
1600CAST_ACCESSOR(Code)
1601CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001602CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001603CAST_ACCESSOR(Proxy)
1604CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001605CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001606CAST_ACCESSOR(ExternalArray)
1607CAST_ACCESSOR(ExternalByteArray)
1608CAST_ACCESSOR(ExternalUnsignedByteArray)
1609CAST_ACCESSOR(ExternalShortArray)
1610CAST_ACCESSOR(ExternalUnsignedShortArray)
1611CAST_ACCESSOR(ExternalIntArray)
1612CAST_ACCESSOR(ExternalUnsignedIntArray)
1613CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614CAST_ACCESSOR(Struct)
1615
1616
1617#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1618 STRUCT_LIST(MAKE_STRUCT_CAST)
1619#undef MAKE_STRUCT_CAST
1620
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001621
1622template <typename Shape, typename Key>
1623HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624 ASSERT(obj->IsHashTable());
1625 return reinterpret_cast<HashTable*>(obj);
1626}
1627
1628
1629INT_ACCESSORS(Array, length, kLengthOffset)
1630
1631
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001632INT_ACCESSORS(String, length, kLengthOffset)
1633
1634
1635uint32_t String::hash_field() {
1636 return READ_UINT32_FIELD(this, kHashFieldOffset);
1637}
1638
1639
1640void String::set_hash_field(uint32_t value) {
1641 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1642}
1643
1644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645bool String::Equals(String* other) {
1646 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001647 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1648 return false;
1649 }
1650 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651}
1652
1653
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001654Object* String::TryFlatten(PretenureFlag pretenure) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001655 // We don't need to flatten strings that are already flat. Since this code
1656 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001657 if (IsFlat()) return this;
1658 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001659}
1660
1661
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001662uint16_t String::Get(int index) {
1663 ASSERT(index >= 0 && index < length());
1664 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001665 case kSeqStringTag | kAsciiStringTag:
1666 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1667 case kSeqStringTag | kTwoByteStringTag:
1668 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1669 case kConsStringTag | kAsciiStringTag:
1670 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001672 case kExternalStringTag | kAsciiStringTag:
1673 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1674 case kExternalStringTag | kTwoByteStringTag:
1675 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001676 default:
1677 break;
1678 }
1679
1680 UNREACHABLE();
1681 return 0;
1682}
1683
1684
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001685void String::Set(int index, uint16_t value) {
1686 ASSERT(index >= 0 && index < length());
1687 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688
ager@chromium.org5ec48922009-05-05 07:25:34 +00001689 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001690 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1691 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692}
1693
1694
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001695bool String::IsFlat() {
1696 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001697 case kConsStringTag: {
1698 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001699 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001700 return second->length() == 0;
1701 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001702 default:
1703 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001704 }
1705}
1706
1707
ager@chromium.org7c537e22008-10-16 08:43:32 +00001708uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001709 ASSERT(index >= 0 && index < length());
1710 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1711}
1712
1713
ager@chromium.org7c537e22008-10-16 08:43:32 +00001714void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1716 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1717 static_cast<byte>(value));
1718}
1719
1720
ager@chromium.org7c537e22008-10-16 08:43:32 +00001721Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722 return FIELD_ADDR(this, kHeaderSize);
1723}
1724
1725
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001726char* SeqAsciiString::GetChars() {
1727 return reinterpret_cast<char*>(GetCharsAddress());
1728}
1729
1730
ager@chromium.org7c537e22008-10-16 08:43:32 +00001731Address SeqTwoByteString::GetCharsAddress() {
1732 return FIELD_ADDR(this, kHeaderSize);
1733}
1734
1735
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001736uc16* SeqTwoByteString::GetChars() {
1737 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1738}
1739
1740
ager@chromium.org7c537e22008-10-16 08:43:32 +00001741uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742 ASSERT(index >= 0 && index < length());
1743 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1744}
1745
1746
ager@chromium.org7c537e22008-10-16 08:43:32 +00001747void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 ASSERT(index >= 0 && index < length());
1749 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1750}
1751
1752
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001753int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001755 return SizeFor(length);
1756}
1757
1758
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001759int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761 return SizeFor(length);
1762}
1763
1764
ager@chromium.org870a0b62008-11-04 11:43:05 +00001765String* ConsString::first() {
1766 return String::cast(READ_FIELD(this, kFirstOffset));
1767}
1768
1769
1770Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 return READ_FIELD(this, kFirstOffset);
1772}
1773
1774
ager@chromium.org870a0b62008-11-04 11:43:05 +00001775void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001777 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778}
1779
1780
ager@chromium.org870a0b62008-11-04 11:43:05 +00001781String* ConsString::second() {
1782 return String::cast(READ_FIELD(this, kSecondOffset));
1783}
1784
1785
1786Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 return READ_FIELD(this, kSecondOffset);
1788}
1789
1790
ager@chromium.org870a0b62008-11-04 11:43:05 +00001791void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001793 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794}
1795
1796
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1798 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1799}
1800
1801
1802void ExternalAsciiString::set_resource(
1803 ExternalAsciiString::Resource* resource) {
1804 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1805}
1806
1807
1808ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1809 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1810}
1811
1812
1813void ExternalTwoByteString::set_resource(
1814 ExternalTwoByteString::Resource* resource) {
1815 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1816}
1817
1818
1819byte ByteArray::get(int index) {
1820 ASSERT(index >= 0 && index < this->length());
1821 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1822}
1823
1824
1825void ByteArray::set(int index, byte value) {
1826 ASSERT(index >= 0 && index < this->length());
1827 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1828}
1829
1830
1831int ByteArray::get_int(int index) {
1832 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1833 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1834}
1835
1836
1837ByteArray* ByteArray::FromDataStartAddress(Address address) {
1838 ASSERT_TAG_ALIGNED(address);
1839 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1840}
1841
1842
1843Address ByteArray::GetDataStartAddress() {
1844 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1845}
1846
1847
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001848uint8_t* PixelArray::external_pointer() {
1849 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1850 return reinterpret_cast<uint8_t*>(ptr);
1851}
1852
1853
1854void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1855 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1856 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1857}
1858
1859
1860uint8_t PixelArray::get(int index) {
1861 ASSERT((index >= 0) && (index < this->length()));
1862 uint8_t* ptr = external_pointer();
1863 return ptr[index];
1864}
1865
1866
1867void PixelArray::set(int index, uint8_t value) {
1868 ASSERT((index >= 0) && (index < this->length()));
1869 uint8_t* ptr = external_pointer();
1870 ptr[index] = value;
1871}
1872
1873
ager@chromium.org3811b432009-10-28 14:53:37 +00001874void* ExternalArray::external_pointer() {
1875 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1876 return reinterpret_cast<void*>(ptr);
1877}
1878
1879
1880void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1881 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1882 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1883}
1884
1885
1886int8_t ExternalByteArray::get(int index) {
1887 ASSERT((index >= 0) && (index < this->length()));
1888 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1889 return ptr[index];
1890}
1891
1892
1893void ExternalByteArray::set(int index, int8_t value) {
1894 ASSERT((index >= 0) && (index < this->length()));
1895 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1896 ptr[index] = value;
1897}
1898
1899
1900uint8_t ExternalUnsignedByteArray::get(int index) {
1901 ASSERT((index >= 0) && (index < this->length()));
1902 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1903 return ptr[index];
1904}
1905
1906
1907void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1908 ASSERT((index >= 0) && (index < this->length()));
1909 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1910 ptr[index] = value;
1911}
1912
1913
1914int16_t ExternalShortArray::get(int index) {
1915 ASSERT((index >= 0) && (index < this->length()));
1916 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1917 return ptr[index];
1918}
1919
1920
1921void ExternalShortArray::set(int index, int16_t value) {
1922 ASSERT((index >= 0) && (index < this->length()));
1923 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1924 ptr[index] = value;
1925}
1926
1927
1928uint16_t ExternalUnsignedShortArray::get(int index) {
1929 ASSERT((index >= 0) && (index < this->length()));
1930 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1931 return ptr[index];
1932}
1933
1934
1935void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1936 ASSERT((index >= 0) && (index < this->length()));
1937 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1938 ptr[index] = value;
1939}
1940
1941
1942int32_t ExternalIntArray::get(int index) {
1943 ASSERT((index >= 0) && (index < this->length()));
1944 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1945 return ptr[index];
1946}
1947
1948
1949void ExternalIntArray::set(int index, int32_t value) {
1950 ASSERT((index >= 0) && (index < this->length()));
1951 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1952 ptr[index] = value;
1953}
1954
1955
1956uint32_t ExternalUnsignedIntArray::get(int index) {
1957 ASSERT((index >= 0) && (index < this->length()));
1958 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1959 return ptr[index];
1960}
1961
1962
1963void ExternalUnsignedIntArray::set(int index, uint32_t value) {
1964 ASSERT((index >= 0) && (index < this->length()));
1965 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1966 ptr[index] = value;
1967}
1968
1969
1970float ExternalFloatArray::get(int index) {
1971 ASSERT((index >= 0) && (index < this->length()));
1972 float* ptr = static_cast<float*>(external_pointer());
1973 return ptr[index];
1974}
1975
1976
1977void ExternalFloatArray::set(int index, float value) {
1978 ASSERT((index >= 0) && (index < this->length()));
1979 float* ptr = static_cast<float*>(external_pointer());
1980 ptr[index] = value;
1981}
1982
1983
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001984int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001985 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
1986}
1987
1988
1989int Map::inobject_properties() {
1990 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991}
1992
1993
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001994int Map::pre_allocated_property_fields() {
1995 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
1996}
1997
1998
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001999int HeapObject::SizeFromMap(Map* map) {
2000 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002001 // Only inline the most frequent cases.
2002 if (instance_type == JS_OBJECT_TYPE ||
2003 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2004 (kStringTag | kConsStringTag) ||
2005 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006 if (instance_type == FIXED_ARRAY_TYPE) {
2007 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2008 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002009 if (instance_type == BYTE_ARRAY_TYPE) {
2010 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2011 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012 // Otherwise do the general size computation.
2013 return SlowSizeFromMap(map);
2014}
2015
2016
2017void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002018 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002019 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002020 ASSERT(0 <= value && value < 256);
2021 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2022}
2023
2024
ager@chromium.org7c537e22008-10-16 08:43:32 +00002025void Map::set_inobject_properties(int value) {
2026 ASSERT(0 <= value && value < 256);
2027 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2028}
2029
2030
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002031void Map::set_pre_allocated_property_fields(int value) {
2032 ASSERT(0 <= value && value < 256);
2033 WRITE_BYTE_FIELD(this,
2034 kPreAllocatedPropertyFieldsOffset,
2035 static_cast<byte>(value));
2036}
2037
2038
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039InstanceType Map::instance_type() {
2040 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2041}
2042
2043
2044void Map::set_instance_type(InstanceType value) {
2045 ASSERT(0 <= value && value < 256);
2046 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2047}
2048
2049
2050int Map::unused_property_fields() {
2051 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2052}
2053
2054
2055void Map::set_unused_property_fields(int value) {
2056 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2057}
2058
2059
2060byte Map::bit_field() {
2061 return READ_BYTE_FIELD(this, kBitFieldOffset);
2062}
2063
2064
2065void Map::set_bit_field(byte value) {
2066 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2067}
2068
2069
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002070byte Map::bit_field2() {
2071 return READ_BYTE_FIELD(this, kBitField2Offset);
2072}
2073
2074
2075void Map::set_bit_field2(byte value) {
2076 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2077}
2078
2079
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002080void Map::set_non_instance_prototype(bool value) {
2081 if (value) {
2082 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2083 } else {
2084 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2085 }
2086}
2087
2088
2089bool Map::has_non_instance_prototype() {
2090 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2091}
2092
2093
ager@chromium.org870a0b62008-11-04 11:43:05 +00002094void Map::set_is_access_check_needed(bool access_check_needed) {
2095 if (access_check_needed) {
2096 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2097 } else {
2098 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2099 }
2100}
2101
2102
2103bool Map::is_access_check_needed() {
2104 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2105}
2106
2107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108Code::Flags Code::flags() {
2109 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2110}
2111
2112
2113void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002114 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002115 // Make sure that all call stubs have an arguments count.
2116 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2117 ExtractArgumentsCountFromFlags(flags) >= 0);
2118 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2119}
2120
2121
2122Code::Kind Code::kind() {
2123 return ExtractKindFromFlags(flags());
2124}
2125
2126
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002127InLoopFlag Code::ic_in_loop() {
2128 return ExtractICInLoopFromFlags(flags());
2129}
2130
2131
kasper.lund7276f142008-07-30 08:49:36 +00002132InlineCacheState Code::ic_state() {
2133 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 // Only allow uninitialized or debugger states for non-IC code
2135 // objects. This is used in the debugger to determine whether or not
2136 // a call to code object has been replaced with a debug break call.
2137 ASSERT(is_inline_cache_stub() ||
2138 result == UNINITIALIZED ||
2139 result == DEBUG_BREAK ||
2140 result == DEBUG_PREPARE_STEP_IN);
2141 return result;
2142}
2143
2144
2145PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002146 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147 return ExtractTypeFromFlags(flags());
2148}
2149
2150
2151int Code::arguments_count() {
2152 ASSERT(is_call_stub() || kind() == STUB);
2153 return ExtractArgumentsCountFromFlags(flags());
2154}
2155
2156
2157CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002158 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002159 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2160 kStubMajorKeyOffset));
2161}
2162
2163
2164void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002165 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002166 ASSERT(0 <= major && major < 256);
2167 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002168}
2169
2170
2171bool Code::is_inline_cache_stub() {
2172 Kind kind = this->kind();
2173 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2174}
2175
2176
2177Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002178 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002179 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180 PropertyType type,
2181 int argc) {
2182 // Compute the bit mask.
2183 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002184 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002185 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186 bits |= type << kFlagsTypeShift;
2187 bits |= argc << kFlagsArgumentsCountShift;
2188 // Cast to flags and validate result before returning it.
2189 Flags result = static_cast<Flags>(bits);
2190 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002191 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002192 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193 ASSERT(ExtractTypeFromFlags(result) == type);
2194 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2195 return result;
2196}
2197
2198
2199Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2200 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002201 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002203 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
2207Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2208 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2209 return static_cast<Kind>(bits);
2210}
2211
2212
kasper.lund7276f142008-07-30 08:49:36 +00002213InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2214 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215 return static_cast<InlineCacheState>(bits);
2216}
2217
2218
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002219InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2220 int bits = (flags & kFlagsICInLoopMask);
2221 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2222}
2223
2224
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2226 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2227 return static_cast<PropertyType>(bits);
2228}
2229
2230
2231int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2232 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2233}
2234
2235
2236Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2237 int bits = flags & ~kFlagsTypeMask;
2238 return static_cast<Flags>(bits);
2239}
2240
2241
ager@chromium.org8bb60582008-12-11 12:02:20 +00002242Code* Code::GetCodeFromTargetAddress(Address address) {
2243 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2244 // GetCodeFromTargetAddress might be called when marking objects during mark
2245 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2246 // Code::cast. Code::cast does not work when the object's map is
2247 // marked.
2248 Code* result = reinterpret_cast<Code*>(code);
2249 return result;
2250}
2251
2252
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253Object* Map::prototype() {
2254 return READ_FIELD(this, kPrototypeOffset);
2255}
2256
2257
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002258void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 ASSERT(value->IsNull() || value->IsJSObject());
2260 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002261 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002262}
2263
2264
2265ACCESSORS(Map, instance_descriptors, DescriptorArray,
2266 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002267ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002268ACCESSORS(Map, constructor, Object, kConstructorOffset)
2269
2270ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2271ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2272
2273ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2274ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002275ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002277ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278
2279ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2280ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2281ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2282ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2283ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002284ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285
2286ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2287ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2288ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2289
2290ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2291ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2292ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2293ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2294ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2295ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2296
2297ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2298ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2299
2300ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2301ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2302
2303ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2304ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2306 kPropertyAccessorsOffset)
2307ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2308 kPrototypeTemplateOffset)
2309ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2310ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2311 kNamedPropertyHandlerOffset)
2312ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2313 kIndexedPropertyHandlerOffset)
2314ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2315 kInstanceTemplateOffset)
2316ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2317ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2319 kInstanceCallHandlerOffset)
2320ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2321 kAccessCheckInfoOffset)
2322ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2323
2324ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002325ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2326 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327
2328ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2329ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2330
2331ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2332
2333ACCESSORS(Script, source, Object, kSourceOffset)
2334ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002335ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002336ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2337ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002338ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002339ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002340ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2341ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002342ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002343ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002344ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002345ACCESSORS(Script, eval_from_instructions_offset, Smi,
2346 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002348#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002349ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2350ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2351ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2352ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2353
2354ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2355ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2356ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2357ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002358#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002360ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2362ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2363 kInstanceClassNameOffset)
2364ACCESSORS(SharedFunctionInfo, function_data, Object,
2365 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2367ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002368ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002369ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2370 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371
2372BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2373 kHiddenPrototypeBit)
2374BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2375BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2376 kNeedsAccessCheckBit)
2377BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2378 kIsExpressionBit)
2379BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2380 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002381BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002382 has_only_simple_this_property_assignments,
2383 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002384BOOL_ACCESSORS(SharedFunctionInfo,
2385 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002386 try_full_codegen,
2387 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388
2389INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2390INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2391 kFormalParameterCountOffset)
2392INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2393 kExpectedNofPropertiesOffset)
2394INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2395 kStartPositionAndTypeOffset)
2396INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2397INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2398 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002399INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2400 kCompilerHintsOffset)
2401INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2402 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403
2404
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002405ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2406ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2407
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002408bool Script::HasValidSource() {
2409 Object* src = this->source();
2410 if (!src->IsString()) return true;
2411 String* src_str = String::cast(src);
2412 if (!StringShape(src_str).IsExternal()) return true;
2413 if (src_str->IsAsciiRepresentation()) {
2414 return ExternalAsciiString::cast(src)->resource() != NULL;
2415 } else if (src_str->IsTwoByteRepresentation()) {
2416 return ExternalTwoByteString::cast(src)->resource() != NULL;
2417 }
2418 return true;
2419}
2420
2421
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002422void SharedFunctionInfo::DontAdaptArguments() {
2423 ASSERT(code()->kind() == Code::BUILTIN);
2424 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2425}
2426
2427
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428int SharedFunctionInfo::start_position() {
2429 return start_position_and_type() >> kStartPositionShift;
2430}
2431
2432
2433void SharedFunctionInfo::set_start_position(int start_position) {
2434 set_start_position_and_type((start_position << kStartPositionShift)
2435 | (start_position_and_type() & ~kStartPositionMask));
2436}
2437
2438
2439Code* SharedFunctionInfo::code() {
2440 return Code::cast(READ_FIELD(this, kCodeOffset));
2441}
2442
2443
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002444void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002446 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002447}
2448
2449
2450bool SharedFunctionInfo::is_compiled() {
2451 // TODO(1242782): Create a code kind for uncompiled code.
2452 return code()->kind() != Code::STUB;
2453}
2454
2455
2456bool JSFunction::IsBoilerplate() {
2457 return map() == Heap::boilerplate_function_map();
2458}
2459
2460
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002461bool JSFunction::IsBuiltin() {
2462 return context()->global()->IsJSBuiltinsObject();
2463}
2464
2465
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002466bool JSObject::IsLoaded() {
2467 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468}
2469
2470
2471Code* JSFunction::code() {
2472 return shared()->code();
2473}
2474
2475
2476void JSFunction::set_code(Code* value) {
2477 shared()->set_code(value);
2478}
2479
2480
2481Context* JSFunction::context() {
2482 return Context::cast(READ_FIELD(this, kContextOffset));
2483}
2484
2485
2486Object* JSFunction::unchecked_context() {
2487 return READ_FIELD(this, kContextOffset);
2488}
2489
2490
2491void JSFunction::set_context(Object* value) {
2492 ASSERT(value == Heap::undefined_value() || value->IsContext());
2493 WRITE_FIELD(this, kContextOffset, value);
2494 WRITE_BARRIER(this, kContextOffset);
2495}
2496
2497ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2498 kPrototypeOrInitialMapOffset)
2499
2500
2501Map* JSFunction::initial_map() {
2502 return Map::cast(prototype_or_initial_map());
2503}
2504
2505
2506void JSFunction::set_initial_map(Map* value) {
2507 set_prototype_or_initial_map(value);
2508}
2509
2510
2511bool JSFunction::has_initial_map() {
2512 return prototype_or_initial_map()->IsMap();
2513}
2514
2515
2516bool JSFunction::has_instance_prototype() {
2517 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2518}
2519
2520
2521bool JSFunction::has_prototype() {
2522 return map()->has_non_instance_prototype() || has_instance_prototype();
2523}
2524
2525
2526Object* JSFunction::instance_prototype() {
2527 ASSERT(has_instance_prototype());
2528 if (has_initial_map()) return initial_map()->prototype();
2529 // When there is no initial map and the prototype is a JSObject, the
2530 // initial map field is used for the prototype field.
2531 return prototype_or_initial_map();
2532}
2533
2534
2535Object* JSFunction::prototype() {
2536 ASSERT(has_prototype());
2537 // If the function's prototype property has been set to a non-JSObject
2538 // value, that value is stored in the constructor field of the map.
2539 if (map()->has_non_instance_prototype()) return map()->constructor();
2540 return instance_prototype();
2541}
2542
2543
2544bool JSFunction::is_compiled() {
2545 return shared()->is_compiled();
2546}
2547
2548
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002549int JSFunction::NumberOfLiterals() {
2550 return literals()->length();
2551}
2552
2553
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002554Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2555 ASSERT(0 <= id && id < kJSBuiltinsCount);
2556 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2557}
2558
2559
2560void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2561 Object* value) {
2562 ASSERT(0 <= id && id < kJSBuiltinsCount);
2563 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2564 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2565}
2566
2567
2568Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002569 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002570}
2571
2572
2573void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002574 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575}
2576
2577
2578void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2579 visitor->VisitExternalReference(
2580 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2581}
2582
2583
2584ACCESSORS(JSValue, value, Object, kValueOffset)
2585
2586
2587JSValue* JSValue::cast(Object* obj) {
2588 ASSERT(obj->IsJSValue());
2589 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2590 return reinterpret_cast<JSValue*>(obj);
2591}
2592
2593
2594INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2595INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2596INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2597
2598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599byte* Code::instruction_start() {
2600 return FIELD_ADDR(this, kHeaderSize);
2601}
2602
2603
2604int Code::body_size() {
2605 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2606}
2607
2608
2609byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002610 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002611}
2612
2613
2614byte* Code::entry() {
2615 return instruction_start();
2616}
2617
2618
2619bool Code::contains(byte* pc) {
2620 return (instruction_start() <= pc) &&
2621 (pc < instruction_start() + instruction_size());
2622}
2623
2624
2625byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002626 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002627}
2628
2629
2630ACCESSORS(JSArray, length, Object, kLengthOffset)
2631
2632
ager@chromium.org236ad962008-09-25 09:45:57 +00002633ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002634
2635
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002636JSRegExp::Type JSRegExp::TypeTag() {
2637 Object* data = this->data();
2638 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2639 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2640 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002641}
2642
2643
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002644int JSRegExp::CaptureCount() {
2645 switch (TypeTag()) {
2646 case ATOM:
2647 return 0;
2648 case IRREGEXP:
2649 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2650 default:
2651 UNREACHABLE();
2652 return -1;
2653 }
2654}
2655
2656
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002657JSRegExp::Flags JSRegExp::GetFlags() {
2658 ASSERT(this->data()->IsFixedArray());
2659 Object* data = this->data();
2660 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2661 return Flags(smi->value());
2662}
2663
2664
2665String* JSRegExp::Pattern() {
2666 ASSERT(this->data()->IsFixedArray());
2667 Object* data = this->data();
2668 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2669 return pattern;
2670}
2671
2672
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002673Object* JSRegExp::DataAt(int index) {
2674 ASSERT(TypeTag() != NOT_COMPILED);
2675 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002676}
2677
2678
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002679void JSRegExp::SetDataAt(int index, Object* value) {
2680 ASSERT(TypeTag() != NOT_COMPILED);
2681 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2682 FixedArray::cast(data())->set(index, value);
2683}
2684
2685
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002686JSObject::ElementsKind JSObject::GetElementsKind() {
2687 Array* array = elements();
2688 if (array->IsFixedArray()) {
2689 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2690 if (array->map() == Heap::fixed_array_map()) {
2691 return FAST_ELEMENTS;
2692 }
2693 ASSERT(array->IsDictionary());
2694 return DICTIONARY_ELEMENTS;
2695 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002696 if (array->IsExternalArray()) {
2697 switch (array->map()->instance_type()) {
2698 case EXTERNAL_BYTE_ARRAY_TYPE:
2699 return EXTERNAL_BYTE_ELEMENTS;
2700 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2701 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2702 case EXTERNAL_SHORT_ARRAY_TYPE:
2703 return EXTERNAL_SHORT_ELEMENTS;
2704 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2705 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2706 case EXTERNAL_INT_ARRAY_TYPE:
2707 return EXTERNAL_INT_ELEMENTS;
2708 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2709 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2710 default:
2711 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2712 return EXTERNAL_FLOAT_ELEMENTS;
2713 }
2714 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002715 ASSERT(array->IsPixelArray());
2716 return PIXEL_ELEMENTS;
2717}
2718
2719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002720bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002721 return GetElementsKind() == FAST_ELEMENTS;
2722}
2723
2724
2725bool JSObject::HasDictionaryElements() {
2726 return GetElementsKind() == DICTIONARY_ELEMENTS;
2727}
2728
2729
2730bool JSObject::HasPixelElements() {
2731 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732}
2733
2734
ager@chromium.org3811b432009-10-28 14:53:37 +00002735bool JSObject::HasExternalArrayElements() {
2736 return (HasExternalByteElements() ||
2737 HasExternalUnsignedByteElements() ||
2738 HasExternalShortElements() ||
2739 HasExternalUnsignedShortElements() ||
2740 HasExternalIntElements() ||
2741 HasExternalUnsignedIntElements() ||
2742 HasExternalFloatElements());
2743}
2744
2745
2746bool JSObject::HasExternalByteElements() {
2747 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2748}
2749
2750
2751bool JSObject::HasExternalUnsignedByteElements() {
2752 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2753}
2754
2755
2756bool JSObject::HasExternalShortElements() {
2757 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2758}
2759
2760
2761bool JSObject::HasExternalUnsignedShortElements() {
2762 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2763}
2764
2765
2766bool JSObject::HasExternalIntElements() {
2767 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2768}
2769
2770
2771bool JSObject::HasExternalUnsignedIntElements() {
2772 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2773}
2774
2775
2776bool JSObject::HasExternalFloatElements() {
2777 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2778}
2779
2780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002781bool JSObject::HasNamedInterceptor() {
2782 return map()->has_named_interceptor();
2783}
2784
2785
2786bool JSObject::HasIndexedInterceptor() {
2787 return map()->has_indexed_interceptor();
2788}
2789
2790
ager@chromium.org5c838252010-02-19 08:53:10 +00002791bool JSObject::AllowsSetElementsLength() {
2792 bool result = elements()->IsFixedArray();
2793 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2794 return result;
2795}
2796
2797
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002798StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002799 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002800 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002801}
2802
2803
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002804NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002805 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002806 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807}
2808
2809
2810bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002811 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812}
2813
2814
2815uint32_t String::Hash() {
2816 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002817 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002818 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002819 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820 return ComputeAndSetHash();
2821}
2822
2823
ager@chromium.org7c537e22008-10-16 08:43:32 +00002824StringHasher::StringHasher(int length)
2825 : length_(length),
2826 raw_running_hash_(0),
2827 array_index_(0),
2828 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2829 is_first_char_(true),
2830 is_valid_(true) { }
2831
2832
2833bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002834 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002835}
2836
2837
2838void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002839 // Use the Jenkins one-at-a-time hash function to update the hash
2840 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002841 raw_running_hash_ += c;
2842 raw_running_hash_ += (raw_running_hash_ << 10);
2843 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002844 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002845 if (is_array_index_) {
2846 if (c < '0' || c > '9') {
2847 is_array_index_ = false;
2848 } else {
2849 int d = c - '0';
2850 if (is_first_char_) {
2851 is_first_char_ = false;
2852 if (c == '0' && length_ > 1) {
2853 is_array_index_ = false;
2854 return;
2855 }
2856 }
2857 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2858 is_array_index_ = false;
2859 } else {
2860 array_index_ = array_index_ * 10 + d;
2861 }
2862 }
2863 }
2864}
2865
2866
2867void StringHasher::AddCharacterNoIndex(uc32 c) {
2868 ASSERT(!is_array_index());
2869 raw_running_hash_ += c;
2870 raw_running_hash_ += (raw_running_hash_ << 10);
2871 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2872}
2873
2874
2875uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002876 // Get the calculated raw hash value and do some more bit ops to distribute
2877 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002878 uint32_t result = raw_running_hash_;
2879 result += (result << 3);
2880 result ^= (result >> 11);
2881 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002882 if (result == 0) {
2883 result = 27;
2884 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002885 return result;
2886}
2887
2888
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002889bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002890 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002891 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002892 return SlowAsArrayIndex(index);
2893}
2894
2895
2896Object* JSObject::GetPrototype() {
2897 return JSObject::cast(this)->map()->prototype();
2898}
2899
2900
2901PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2902 return GetPropertyAttributeWithReceiver(this, key);
2903}
2904
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002905// TODO(504): this may be useful in other places too where JSGlobalProxy
2906// is used.
2907Object* JSObject::BypassGlobalProxy() {
2908 if (IsJSGlobalProxy()) {
2909 Object* proto = GetPrototype();
2910 if (proto->IsNull()) return Heap::undefined_value();
2911 ASSERT(proto->IsJSGlobalObject());
2912 return proto;
2913 }
2914 return this;
2915}
2916
2917
2918bool JSObject::HasHiddenPropertiesObject() {
2919 ASSERT(!IsJSGlobalProxy());
2920 return GetPropertyAttributePostInterceptor(this,
2921 Heap::hidden_symbol(),
2922 false) != ABSENT;
2923}
2924
2925
2926Object* JSObject::GetHiddenPropertiesObject() {
2927 ASSERT(!IsJSGlobalProxy());
2928 PropertyAttributes attributes;
2929 return GetLocalPropertyPostInterceptor(this,
2930 Heap::hidden_symbol(),
2931 &attributes);
2932}
2933
2934
2935Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2936 ASSERT(!IsJSGlobalProxy());
2937 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2938 hidden_obj,
2939 DONT_ENUM);
2940}
2941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942
2943bool JSObject::HasElement(uint32_t index) {
2944 return HasElementWithReceiver(this, index);
2945}
2946
2947
2948bool AccessorInfo::all_can_read() {
2949 return BooleanBit::get(flag(), kAllCanReadBit);
2950}
2951
2952
2953void AccessorInfo::set_all_can_read(bool value) {
2954 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2955}
2956
2957
2958bool AccessorInfo::all_can_write() {
2959 return BooleanBit::get(flag(), kAllCanWriteBit);
2960}
2961
2962
2963void AccessorInfo::set_all_can_write(bool value) {
2964 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2965}
2966
2967
ager@chromium.org870a0b62008-11-04 11:43:05 +00002968bool AccessorInfo::prohibits_overwriting() {
2969 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2970}
2971
2972
2973void AccessorInfo::set_prohibits_overwriting(bool value) {
2974 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
2975}
2976
2977
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978PropertyAttributes AccessorInfo::property_attributes() {
2979 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
2980}
2981
2982
2983void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
2984 ASSERT(AttributesField::is_valid(attributes));
2985 int rest_value = flag()->value() & ~AttributesField::mask();
2986 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
2987}
2988
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002989template<typename Shape, typename Key>
2990void Dictionary<Shape, Key>::SetEntry(int entry,
2991 Object* key,
2992 Object* value,
2993 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002994 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002995 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002996 AssertNoAllocation no_gc;
2997 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002998 FixedArray::set(index, key, mode);
2999 FixedArray::set(index+1, value, mode);
3000 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003001}
3002
3003
3004void Map::ClearCodeCache() {
3005 // No write barrier is needed since empty_fixed_array is not in new space.
3006 // Please note this function is used during marking:
3007 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003008 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3009 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003010}
3011
3012
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003013void JSArray::EnsureSize(int required_size) {
3014 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003015 Array* elts = elements();
3016 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3017 if (elts->length() < required_size) {
3018 // Doubling in size would be overkill, but leave some slack to avoid
3019 // constantly growing.
3020 Expand(required_size + (required_size >> 3));
3021 // It's a performance benefit to keep a frequently used array in new-space.
3022 } else if (!Heap::new_space()->Contains(elts) &&
3023 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3024 // Expand will allocate a new backing store in new space even if the size
3025 // we asked for isn't larger than what we had before.
3026 Expand(required_size);
3027 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003028}
3029
3030
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003031void JSArray::set_length(Smi* length) {
3032 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3033}
3034
3035
ager@chromium.org7c537e22008-10-16 08:43:32 +00003036void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003037 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003038 set_elements(storage);
3039}
3040
3041
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003042Object* FixedArray::Copy() {
3043 if (length() == 0) return this;
3044 return Heap::CopyFixedArray(this);
3045}
3046
3047
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003048#undef CAST_ACCESSOR
3049#undef INT_ACCESSORS
3050#undef SMI_ACCESSORS
3051#undef ACCESSORS
3052#undef FIELD_ADDR
3053#undef READ_FIELD
3054#undef WRITE_FIELD
3055#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003056#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057#undef READ_MEMADDR_FIELD
3058#undef WRITE_MEMADDR_FIELD
3059#undef READ_DOUBLE_FIELD
3060#undef WRITE_DOUBLE_FIELD
3061#undef READ_INT_FIELD
3062#undef WRITE_INT_FIELD
3063#undef READ_SHORT_FIELD
3064#undef WRITE_SHORT_FIELD
3065#undef READ_BYTE_FIELD
3066#undef WRITE_BYTE_FIELD
3067
3068
3069} } // namespace v8::internal
3070
3071#endif // V8_OBJECTS_INL_H_