blob: 4cc9b9f8340238549a12136218672eb205771007 [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)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002364ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2366ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002367ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002368ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2369 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370
2371BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2372 kHiddenPrototypeBit)
2373BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2374BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2375 kNeedsAccessCheckBit)
2376BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2377 kIsExpressionBit)
2378BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2379 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002380BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002381 has_only_simple_this_property_assignments,
2382 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002383BOOL_ACCESSORS(SharedFunctionInfo,
2384 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002385 try_full_codegen,
2386 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387
2388INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2389INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2390 kFormalParameterCountOffset)
2391INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2392 kExpectedNofPropertiesOffset)
2393INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2394 kStartPositionAndTypeOffset)
2395INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2396INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2397 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002398INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2399 kCompilerHintsOffset)
2400INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2401 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402
2403
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002404ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2405ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2406
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002407bool Script::HasValidSource() {
2408 Object* src = this->source();
2409 if (!src->IsString()) return true;
2410 String* src_str = String::cast(src);
2411 if (!StringShape(src_str).IsExternal()) return true;
2412 if (src_str->IsAsciiRepresentation()) {
2413 return ExternalAsciiString::cast(src)->resource() != NULL;
2414 } else if (src_str->IsTwoByteRepresentation()) {
2415 return ExternalTwoByteString::cast(src)->resource() != NULL;
2416 }
2417 return true;
2418}
2419
2420
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002421void SharedFunctionInfo::DontAdaptArguments() {
2422 ASSERT(code()->kind() == Code::BUILTIN);
2423 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2424}
2425
2426
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427int SharedFunctionInfo::start_position() {
2428 return start_position_and_type() >> kStartPositionShift;
2429}
2430
2431
2432void SharedFunctionInfo::set_start_position(int start_position) {
2433 set_start_position_and_type((start_position << kStartPositionShift)
2434 | (start_position_and_type() & ~kStartPositionMask));
2435}
2436
2437
2438Code* SharedFunctionInfo::code() {
2439 return Code::cast(READ_FIELD(this, kCodeOffset));
2440}
2441
2442
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002443void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002444 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002445 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002446}
2447
2448
2449bool SharedFunctionInfo::is_compiled() {
2450 // TODO(1242782): Create a code kind for uncompiled code.
2451 return code()->kind() != Code::STUB;
2452}
2453
2454
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002455bool SharedFunctionInfo::IsApiFunction() {
2456 return function_data()->IsFunctionTemplateInfo();
2457}
2458
2459
2460FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2461 ASSERT(IsApiFunction());
2462 return FunctionTemplateInfo::cast(function_data());
2463}
2464
2465
2466bool SharedFunctionInfo::HasCustomCallGenerator() {
2467 return function_data()->IsProxy();
2468}
2469
2470
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002471bool JSFunction::IsBoilerplate() {
2472 return map() == Heap::boilerplate_function_map();
2473}
2474
2475
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002476bool JSFunction::IsBuiltin() {
2477 return context()->global()->IsJSBuiltinsObject();
2478}
2479
2480
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002481bool JSObject::IsLoaded() {
2482 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002483}
2484
2485
2486Code* JSFunction::code() {
2487 return shared()->code();
2488}
2489
2490
2491void JSFunction::set_code(Code* value) {
2492 shared()->set_code(value);
2493}
2494
2495
2496Context* JSFunction::context() {
2497 return Context::cast(READ_FIELD(this, kContextOffset));
2498}
2499
2500
2501Object* JSFunction::unchecked_context() {
2502 return READ_FIELD(this, kContextOffset);
2503}
2504
2505
2506void JSFunction::set_context(Object* value) {
2507 ASSERT(value == Heap::undefined_value() || value->IsContext());
2508 WRITE_FIELD(this, kContextOffset, value);
2509 WRITE_BARRIER(this, kContextOffset);
2510}
2511
2512ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2513 kPrototypeOrInitialMapOffset)
2514
2515
2516Map* JSFunction::initial_map() {
2517 return Map::cast(prototype_or_initial_map());
2518}
2519
2520
2521void JSFunction::set_initial_map(Map* value) {
2522 set_prototype_or_initial_map(value);
2523}
2524
2525
2526bool JSFunction::has_initial_map() {
2527 return prototype_or_initial_map()->IsMap();
2528}
2529
2530
2531bool JSFunction::has_instance_prototype() {
2532 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2533}
2534
2535
2536bool JSFunction::has_prototype() {
2537 return map()->has_non_instance_prototype() || has_instance_prototype();
2538}
2539
2540
2541Object* JSFunction::instance_prototype() {
2542 ASSERT(has_instance_prototype());
2543 if (has_initial_map()) return initial_map()->prototype();
2544 // When there is no initial map and the prototype is a JSObject, the
2545 // initial map field is used for the prototype field.
2546 return prototype_or_initial_map();
2547}
2548
2549
2550Object* JSFunction::prototype() {
2551 ASSERT(has_prototype());
2552 // If the function's prototype property has been set to a non-JSObject
2553 // value, that value is stored in the constructor field of the map.
2554 if (map()->has_non_instance_prototype()) return map()->constructor();
2555 return instance_prototype();
2556}
2557
2558
2559bool JSFunction::is_compiled() {
2560 return shared()->is_compiled();
2561}
2562
2563
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002564int JSFunction::NumberOfLiterals() {
2565 return literals()->length();
2566}
2567
2568
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002569Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2570 ASSERT(0 <= id && id < kJSBuiltinsCount);
2571 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2572}
2573
2574
2575void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2576 Object* value) {
2577 ASSERT(0 <= id && id < kJSBuiltinsCount);
2578 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2579 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2580}
2581
2582
2583Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002584 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585}
2586
2587
2588void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002589 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590}
2591
2592
2593void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2594 visitor->VisitExternalReference(
2595 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2596}
2597
2598
2599ACCESSORS(JSValue, value, Object, kValueOffset)
2600
2601
2602JSValue* JSValue::cast(Object* obj) {
2603 ASSERT(obj->IsJSValue());
2604 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2605 return reinterpret_cast<JSValue*>(obj);
2606}
2607
2608
2609INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2610INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2611INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2612
2613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002614byte* Code::instruction_start() {
2615 return FIELD_ADDR(this, kHeaderSize);
2616}
2617
2618
2619int Code::body_size() {
2620 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2621}
2622
2623
2624byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002625 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002626}
2627
2628
2629byte* Code::entry() {
2630 return instruction_start();
2631}
2632
2633
2634bool Code::contains(byte* pc) {
2635 return (instruction_start() <= pc) &&
2636 (pc < instruction_start() + instruction_size());
2637}
2638
2639
2640byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002641 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002642}
2643
2644
2645ACCESSORS(JSArray, length, Object, kLengthOffset)
2646
2647
ager@chromium.org236ad962008-09-25 09:45:57 +00002648ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002649
2650
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002651JSRegExp::Type JSRegExp::TypeTag() {
2652 Object* data = this->data();
2653 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2654 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2655 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002656}
2657
2658
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002659int JSRegExp::CaptureCount() {
2660 switch (TypeTag()) {
2661 case ATOM:
2662 return 0;
2663 case IRREGEXP:
2664 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2665 default:
2666 UNREACHABLE();
2667 return -1;
2668 }
2669}
2670
2671
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002672JSRegExp::Flags JSRegExp::GetFlags() {
2673 ASSERT(this->data()->IsFixedArray());
2674 Object* data = this->data();
2675 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2676 return Flags(smi->value());
2677}
2678
2679
2680String* JSRegExp::Pattern() {
2681 ASSERT(this->data()->IsFixedArray());
2682 Object* data = this->data();
2683 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2684 return pattern;
2685}
2686
2687
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002688Object* JSRegExp::DataAt(int index) {
2689 ASSERT(TypeTag() != NOT_COMPILED);
2690 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002691}
2692
2693
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002694void JSRegExp::SetDataAt(int index, Object* value) {
2695 ASSERT(TypeTag() != NOT_COMPILED);
2696 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2697 FixedArray::cast(data())->set(index, value);
2698}
2699
2700
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002701JSObject::ElementsKind JSObject::GetElementsKind() {
2702 Array* array = elements();
2703 if (array->IsFixedArray()) {
2704 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2705 if (array->map() == Heap::fixed_array_map()) {
2706 return FAST_ELEMENTS;
2707 }
2708 ASSERT(array->IsDictionary());
2709 return DICTIONARY_ELEMENTS;
2710 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002711 if (array->IsExternalArray()) {
2712 switch (array->map()->instance_type()) {
2713 case EXTERNAL_BYTE_ARRAY_TYPE:
2714 return EXTERNAL_BYTE_ELEMENTS;
2715 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2716 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2717 case EXTERNAL_SHORT_ARRAY_TYPE:
2718 return EXTERNAL_SHORT_ELEMENTS;
2719 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2720 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2721 case EXTERNAL_INT_ARRAY_TYPE:
2722 return EXTERNAL_INT_ELEMENTS;
2723 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2724 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2725 default:
2726 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2727 return EXTERNAL_FLOAT_ELEMENTS;
2728 }
2729 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002730 ASSERT(array->IsPixelArray());
2731 return PIXEL_ELEMENTS;
2732}
2733
2734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002735bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002736 return GetElementsKind() == FAST_ELEMENTS;
2737}
2738
2739
2740bool JSObject::HasDictionaryElements() {
2741 return GetElementsKind() == DICTIONARY_ELEMENTS;
2742}
2743
2744
2745bool JSObject::HasPixelElements() {
2746 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002747}
2748
2749
ager@chromium.org3811b432009-10-28 14:53:37 +00002750bool JSObject::HasExternalArrayElements() {
2751 return (HasExternalByteElements() ||
2752 HasExternalUnsignedByteElements() ||
2753 HasExternalShortElements() ||
2754 HasExternalUnsignedShortElements() ||
2755 HasExternalIntElements() ||
2756 HasExternalUnsignedIntElements() ||
2757 HasExternalFloatElements());
2758}
2759
2760
2761bool JSObject::HasExternalByteElements() {
2762 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2763}
2764
2765
2766bool JSObject::HasExternalUnsignedByteElements() {
2767 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2768}
2769
2770
2771bool JSObject::HasExternalShortElements() {
2772 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2773}
2774
2775
2776bool JSObject::HasExternalUnsignedShortElements() {
2777 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2778}
2779
2780
2781bool JSObject::HasExternalIntElements() {
2782 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2783}
2784
2785
2786bool JSObject::HasExternalUnsignedIntElements() {
2787 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2788}
2789
2790
2791bool JSObject::HasExternalFloatElements() {
2792 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2793}
2794
2795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002796bool JSObject::HasNamedInterceptor() {
2797 return map()->has_named_interceptor();
2798}
2799
2800
2801bool JSObject::HasIndexedInterceptor() {
2802 return map()->has_indexed_interceptor();
2803}
2804
2805
ager@chromium.org5c838252010-02-19 08:53:10 +00002806bool JSObject::AllowsSetElementsLength() {
2807 bool result = elements()->IsFixedArray();
2808 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2809 return result;
2810}
2811
2812
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002813StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002815 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002816}
2817
2818
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002819NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002820 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002821 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002822}
2823
2824
2825bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002826 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827}
2828
2829
2830uint32_t String::Hash() {
2831 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002832 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002833 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002834 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835 return ComputeAndSetHash();
2836}
2837
2838
ager@chromium.org7c537e22008-10-16 08:43:32 +00002839StringHasher::StringHasher(int length)
2840 : length_(length),
2841 raw_running_hash_(0),
2842 array_index_(0),
2843 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2844 is_first_char_(true),
2845 is_valid_(true) { }
2846
2847
2848bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002849 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002850}
2851
2852
2853void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002854 // Use the Jenkins one-at-a-time hash function to update the hash
2855 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002856 raw_running_hash_ += c;
2857 raw_running_hash_ += (raw_running_hash_ << 10);
2858 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002859 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002860 if (is_array_index_) {
2861 if (c < '0' || c > '9') {
2862 is_array_index_ = false;
2863 } else {
2864 int d = c - '0';
2865 if (is_first_char_) {
2866 is_first_char_ = false;
2867 if (c == '0' && length_ > 1) {
2868 is_array_index_ = false;
2869 return;
2870 }
2871 }
2872 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2873 is_array_index_ = false;
2874 } else {
2875 array_index_ = array_index_ * 10 + d;
2876 }
2877 }
2878 }
2879}
2880
2881
2882void StringHasher::AddCharacterNoIndex(uc32 c) {
2883 ASSERT(!is_array_index());
2884 raw_running_hash_ += c;
2885 raw_running_hash_ += (raw_running_hash_ << 10);
2886 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2887}
2888
2889
2890uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002891 // Get the calculated raw hash value and do some more bit ops to distribute
2892 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002893 uint32_t result = raw_running_hash_;
2894 result += (result << 3);
2895 result ^= (result >> 11);
2896 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002897 if (result == 0) {
2898 result = 27;
2899 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002900 return result;
2901}
2902
2903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002905 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002906 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002907 return SlowAsArrayIndex(index);
2908}
2909
2910
2911Object* JSObject::GetPrototype() {
2912 return JSObject::cast(this)->map()->prototype();
2913}
2914
2915
2916PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2917 return GetPropertyAttributeWithReceiver(this, key);
2918}
2919
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002920// TODO(504): this may be useful in other places too where JSGlobalProxy
2921// is used.
2922Object* JSObject::BypassGlobalProxy() {
2923 if (IsJSGlobalProxy()) {
2924 Object* proto = GetPrototype();
2925 if (proto->IsNull()) return Heap::undefined_value();
2926 ASSERT(proto->IsJSGlobalObject());
2927 return proto;
2928 }
2929 return this;
2930}
2931
2932
2933bool JSObject::HasHiddenPropertiesObject() {
2934 ASSERT(!IsJSGlobalProxy());
2935 return GetPropertyAttributePostInterceptor(this,
2936 Heap::hidden_symbol(),
2937 false) != ABSENT;
2938}
2939
2940
2941Object* JSObject::GetHiddenPropertiesObject() {
2942 ASSERT(!IsJSGlobalProxy());
2943 PropertyAttributes attributes;
2944 return GetLocalPropertyPostInterceptor(this,
2945 Heap::hidden_symbol(),
2946 &attributes);
2947}
2948
2949
2950Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2951 ASSERT(!IsJSGlobalProxy());
2952 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2953 hidden_obj,
2954 DONT_ENUM);
2955}
2956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957
2958bool JSObject::HasElement(uint32_t index) {
2959 return HasElementWithReceiver(this, index);
2960}
2961
2962
2963bool AccessorInfo::all_can_read() {
2964 return BooleanBit::get(flag(), kAllCanReadBit);
2965}
2966
2967
2968void AccessorInfo::set_all_can_read(bool value) {
2969 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2970}
2971
2972
2973bool AccessorInfo::all_can_write() {
2974 return BooleanBit::get(flag(), kAllCanWriteBit);
2975}
2976
2977
2978void AccessorInfo::set_all_can_write(bool value) {
2979 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2980}
2981
2982
ager@chromium.org870a0b62008-11-04 11:43:05 +00002983bool AccessorInfo::prohibits_overwriting() {
2984 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2985}
2986
2987
2988void AccessorInfo::set_prohibits_overwriting(bool value) {
2989 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
2990}
2991
2992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002993PropertyAttributes AccessorInfo::property_attributes() {
2994 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
2995}
2996
2997
2998void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
2999 ASSERT(AttributesField::is_valid(attributes));
3000 int rest_value = flag()->value() & ~AttributesField::mask();
3001 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3002}
3003
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003004template<typename Shape, typename Key>
3005void Dictionary<Shape, Key>::SetEntry(int entry,
3006 Object* key,
3007 Object* value,
3008 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003009 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003010 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003011 AssertNoAllocation no_gc;
3012 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003013 FixedArray::set(index, key, mode);
3014 FixedArray::set(index+1, value, mode);
3015 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003016}
3017
3018
3019void Map::ClearCodeCache() {
3020 // No write barrier is needed since empty_fixed_array is not in new space.
3021 // Please note this function is used during marking:
3022 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003023 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3024 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025}
3026
3027
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003028void JSArray::EnsureSize(int required_size) {
3029 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003030 Array* elts = elements();
3031 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3032 if (elts->length() < required_size) {
3033 // Doubling in size would be overkill, but leave some slack to avoid
3034 // constantly growing.
3035 Expand(required_size + (required_size >> 3));
3036 // It's a performance benefit to keep a frequently used array in new-space.
3037 } else if (!Heap::new_space()->Contains(elts) &&
3038 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3039 // Expand will allocate a new backing store in new space even if the size
3040 // we asked for isn't larger than what we had before.
3041 Expand(required_size);
3042 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003043}
3044
3045
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003046void JSArray::set_length(Smi* length) {
3047 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3048}
3049
3050
ager@chromium.org7c537e22008-10-16 08:43:32 +00003051void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003052 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003053 set_elements(storage);
3054}
3055
3056
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003057Object* FixedArray::Copy() {
3058 if (length() == 0) return this;
3059 return Heap::CopyFixedArray(this);
3060}
3061
3062
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003063#undef CAST_ACCESSOR
3064#undef INT_ACCESSORS
3065#undef SMI_ACCESSORS
3066#undef ACCESSORS
3067#undef FIELD_ADDR
3068#undef READ_FIELD
3069#undef WRITE_FIELD
3070#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003071#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003072#undef READ_MEMADDR_FIELD
3073#undef WRITE_MEMADDR_FIELD
3074#undef READ_DOUBLE_FIELD
3075#undef WRITE_DOUBLE_FIELD
3076#undef READ_INT_FIELD
3077#undef WRITE_INT_FIELD
3078#undef READ_SHORT_FIELD
3079#undef WRITE_SHORT_FIELD
3080#undef READ_BYTE_FIELD
3081#undef WRITE_BYTE_FIELD
3082
3083
3084} } // namespace v8::internal
3085
3086#endif // V8_OBJECTS_INL_H_