blob: c70ab022c6c4b3adccf285ea2365ae602e731b98 [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 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241}
242
243
ager@chromium.org5ec48922009-05-05 07:25:34 +0000244bool String::IsTwoByteRepresentation() {
245 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247}
248
249
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000250bool String::HasOnlyAsciiChars() {
251 uint32_t type = map()->instance_type();
252 return (type & kStringEncodingMask) == kAsciiStringTag ||
253 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000254}
255
256
ager@chromium.org870a0b62008-11-04 11:43:05 +0000257bool StringShape::IsCons() {
258 return (type_ & kStringRepresentationMask) == kConsStringTag;
259}
260
261
ager@chromium.org870a0b62008-11-04 11:43:05 +0000262bool StringShape::IsExternal() {
263 return (type_ & kStringRepresentationMask) == kExternalStringTag;
264}
265
266
267bool StringShape::IsSequential() {
268 return (type_ & kStringRepresentationMask) == kSeqStringTag;
269}
270
271
272StringRepresentationTag StringShape::representation_tag() {
273 uint32_t tag = (type_ & kStringRepresentationMask);
274 return static_cast<StringRepresentationTag>(tag);
275}
276
277
278uint32_t StringShape::full_representation_tag() {
279 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
280}
281
282
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000283STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
284 Internals::kFullStringRepresentationMask);
285
286
ager@chromium.org870a0b62008-11-04 11:43:05 +0000287bool StringShape::IsSequentialAscii() {
288 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
289}
290
291
292bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000293 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000294}
295
296
297bool StringShape::IsExternalAscii() {
298 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
299}
300
301
302bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000303 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000304}
305
306
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000307STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
308 Internals::kExternalTwoByteRepresentationTag);
309
310
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000311uc32 FlatStringReader::Get(int index) {
312 ASSERT(0 <= index && index <= length_);
313 if (is_ascii_) {
314 return static_cast<const byte*>(start_)[index];
315 } else {
316 return static_cast<const uc16*>(start_)[index];
317 }
318}
319
320
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000321bool Object::IsNumber() {
322 return IsSmi() || IsHeapNumber();
323}
324
325
326bool Object::IsByteArray() {
327 return Object::IsHeapObject()
328 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
329}
330
331
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000332bool Object::IsPixelArray() {
333 return Object::IsHeapObject() &&
334 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
335}
336
337
ager@chromium.org3811b432009-10-28 14:53:37 +0000338bool Object::IsExternalArray() {
339 if (!Object::IsHeapObject())
340 return false;
341 InstanceType instance_type =
342 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000343 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
344 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000345}
346
347
348bool Object::IsExternalByteArray() {
349 return Object::IsHeapObject() &&
350 HeapObject::cast(this)->map()->instance_type() ==
351 EXTERNAL_BYTE_ARRAY_TYPE;
352}
353
354
355bool Object::IsExternalUnsignedByteArray() {
356 return Object::IsHeapObject() &&
357 HeapObject::cast(this)->map()->instance_type() ==
358 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
359}
360
361
362bool Object::IsExternalShortArray() {
363 return Object::IsHeapObject() &&
364 HeapObject::cast(this)->map()->instance_type() ==
365 EXTERNAL_SHORT_ARRAY_TYPE;
366}
367
368
369bool Object::IsExternalUnsignedShortArray() {
370 return Object::IsHeapObject() &&
371 HeapObject::cast(this)->map()->instance_type() ==
372 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
373}
374
375
376bool Object::IsExternalIntArray() {
377 return Object::IsHeapObject() &&
378 HeapObject::cast(this)->map()->instance_type() ==
379 EXTERNAL_INT_ARRAY_TYPE;
380}
381
382
383bool Object::IsExternalUnsignedIntArray() {
384 return Object::IsHeapObject() &&
385 HeapObject::cast(this)->map()->instance_type() ==
386 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
387}
388
389
390bool Object::IsExternalFloatArray() {
391 return Object::IsHeapObject() &&
392 HeapObject::cast(this)->map()->instance_type() ==
393 EXTERNAL_FLOAT_ARRAY_TYPE;
394}
395
396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000397bool Object::IsFailure() {
398 return HAS_FAILURE_TAG(this);
399}
400
401
402bool Object::IsRetryAfterGC() {
403 return HAS_FAILURE_TAG(this)
404 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
405}
406
407
ager@chromium.org7c537e22008-10-16 08:43:32 +0000408bool Object::IsOutOfMemoryFailure() {
409 return HAS_FAILURE_TAG(this)
410 && Failure::cast(this)->IsOutOfMemoryException();
411}
412
413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000414bool Object::IsException() {
415 return this == Failure::Exception();
416}
417
418
419bool Object::IsJSObject() {
420 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000421 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422}
423
424
ager@chromium.org32912102009-01-16 10:38:43 +0000425bool Object::IsJSContextExtensionObject() {
426 return IsHeapObject()
427 && (HeapObject::cast(this)->map()->instance_type() ==
428 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
429}
430
431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000432bool Object::IsMap() {
433 return Object::IsHeapObject()
434 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
435}
436
437
438bool Object::IsFixedArray() {
439 return Object::IsHeapObject()
440 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
441}
442
443
444bool Object::IsDescriptorArray() {
445 return IsFixedArray();
446}
447
448
449bool Object::IsContext() {
450 return Object::IsHeapObject()
451 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000452 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000453 HeapObject::cast(this)->map() == Heap::global_context_map());
454}
455
456
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000457bool Object::IsCatchContext() {
458 return Object::IsHeapObject()
459 && HeapObject::cast(this)->map() == Heap::catch_context_map();
460}
461
462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000463bool Object::IsGlobalContext() {
464 return Object::IsHeapObject()
465 && HeapObject::cast(this)->map() == Heap::global_context_map();
466}
467
468
469bool Object::IsJSFunction() {
470 return Object::IsHeapObject()
471 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
472}
473
474
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000475template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476 return obj->IsJSFunction();
477}
478
479
480bool Object::IsCode() {
481 return Object::IsHeapObject()
482 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
483}
484
485
486bool Object::IsOddball() {
487 return Object::IsHeapObject()
488 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
489}
490
491
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000492bool Object::IsJSGlobalPropertyCell() {
493 return Object::IsHeapObject()
494 && HeapObject::cast(this)->map()->instance_type()
495 == JS_GLOBAL_PROPERTY_CELL_TYPE;
496}
497
498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499bool Object::IsSharedFunctionInfo() {
500 return Object::IsHeapObject() &&
501 (HeapObject::cast(this)->map()->instance_type() ==
502 SHARED_FUNCTION_INFO_TYPE);
503}
504
505
506bool Object::IsJSValue() {
507 return Object::IsHeapObject()
508 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
509}
510
511
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000512bool Object::IsStringWrapper() {
513 return IsJSValue() && JSValue::cast(this)->value()->IsString();
514}
515
516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000517bool Object::IsProxy() {
518 return Object::IsHeapObject()
519 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
520}
521
522
523bool Object::IsBoolean() {
524 return IsTrue() || IsFalse();
525}
526
527
528bool Object::IsJSArray() {
529 return Object::IsHeapObject()
530 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
531}
532
533
ager@chromium.org236ad962008-09-25 09:45:57 +0000534bool Object::IsJSRegExp() {
535 return Object::IsHeapObject()
536 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
537}
538
539
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000540template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000541 return obj->IsJSArray();
542}
543
544
545bool Object::IsHashTable() {
546 return Object::IsHeapObject()
547 && HeapObject::cast(this)->map() == Heap::hash_table_map();
548}
549
550
551bool Object::IsDictionary() {
552 return IsHashTable() && this != Heap::symbol_table();
553}
554
555
556bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000557 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558}
559
560
ager@chromium.orgac091b72010-05-05 07:34:42 +0000561bool Object::IsJSFunctionResultCache() {
562 if (!IsFixedArray()) return false;
563 FixedArray* self = FixedArray::cast(this);
564 int length = self->length();
565 if (length < JSFunctionResultCache::kEntriesIndex) return false;
566 if ((length - JSFunctionResultCache::kEntriesIndex)
567 % JSFunctionResultCache::kEntrySize != 0) {
568 return false;
569 }
570#ifdef DEBUG
571 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
572#endif
573 return true;
574}
575
576
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000577bool Object::IsCompilationCacheTable() {
578 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000579}
580
581
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000582bool Object::IsCodeCacheHashTable() {
583 return IsHashTable();
584}
585
586
ager@chromium.org236ad962008-09-25 09:45:57 +0000587bool Object::IsMapCache() {
588 return IsHashTable();
589}
590
591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000592bool Object::IsPrimitive() {
593 return IsOddball() || IsNumber() || IsString();
594}
595
596
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000597bool Object::IsJSGlobalProxy() {
598 bool result = IsHeapObject() &&
599 (HeapObject::cast(this)->map()->instance_type() ==
600 JS_GLOBAL_PROXY_TYPE);
601 ASSERT(!result || IsAccessCheckNeeded());
602 return result;
603}
604
605
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000606bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000607 if (!IsHeapObject()) return false;
608
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000609 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000610 return type == JS_GLOBAL_OBJECT_TYPE ||
611 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612}
613
614
615bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616 return IsHeapObject() &&
617 (HeapObject::cast(this)->map()->instance_type() ==
618 JS_GLOBAL_OBJECT_TYPE);
619}
620
621
622bool Object::IsJSBuiltinsObject() {
623 return IsHeapObject() &&
624 (HeapObject::cast(this)->map()->instance_type() ==
625 JS_BUILTINS_OBJECT_TYPE);
626}
627
628
629bool Object::IsUndetectableObject() {
630 return IsHeapObject()
631 && HeapObject::cast(this)->map()->is_undetectable();
632}
633
634
635bool Object::IsAccessCheckNeeded() {
636 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000637 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
641bool Object::IsStruct() {
642 if (!IsHeapObject()) return false;
643 switch (HeapObject::cast(this)->map()->instance_type()) {
644#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
645 STRUCT_LIST(MAKE_STRUCT_CASE)
646#undef MAKE_STRUCT_CASE
647 default: return false;
648 }
649}
650
651
652#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
653 bool Object::Is##Name() { \
654 return Object::IsHeapObject() \
655 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
656 }
657 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
658#undef MAKE_STRUCT_PREDICATE
659
660
661bool Object::IsUndefined() {
662 return this == Heap::undefined_value();
663}
664
665
666bool Object::IsTheHole() {
667 return this == Heap::the_hole_value();
668}
669
670
671bool Object::IsNull() {
672 return this == Heap::null_value();
673}
674
675
676bool Object::IsTrue() {
677 return this == Heap::true_value();
678}
679
680
681bool Object::IsFalse() {
682 return this == Heap::false_value();
683}
684
685
686double Object::Number() {
687 ASSERT(IsNumber());
688 return IsSmi()
689 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
690 : reinterpret_cast<HeapNumber*>(this)->value();
691}
692
693
694
695Object* Object::ToSmi() {
696 if (IsSmi()) return this;
697 if (IsHeapNumber()) {
698 double value = HeapNumber::cast(this)->value();
699 int int_value = FastD2I(value);
700 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
701 return Smi::FromInt(int_value);
702 }
703 }
704 return Failure::Exception();
705}
706
707
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000708bool Object::HasSpecificClassOf(String* name) {
709 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713Object* Object::GetElement(uint32_t index) {
714 return GetElementWithReceiver(this, index);
715}
716
717
718Object* Object::GetProperty(String* key) {
719 PropertyAttributes attributes;
720 return GetPropertyWithReceiver(this, key, &attributes);
721}
722
723
724Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
725 return GetPropertyWithReceiver(this, key, attributes);
726}
727
728
729#define FIELD_ADDR(p, offset) \
730 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
731
732#define READ_FIELD(p, offset) \
733 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
734
735#define WRITE_FIELD(p, offset, value) \
736 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
737
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000739#define WRITE_BARRIER(object, offset) \
740 Heap::RecordWrite(object->address(), offset);
741
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000742// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000743// write due to the assert validating the written value.
744#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
745 if (mode == UPDATE_WRITE_BARRIER) { \
746 Heap::RecordWrite(object->address(), offset); \
747 } else { \
748 ASSERT(mode == SKIP_WRITE_BARRIER); \
749 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000750 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000751 Page::FromAddress(object->address())-> \
752 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000753 }
754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755#define READ_DOUBLE_FIELD(p, offset) \
756 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
757
758#define WRITE_DOUBLE_FIELD(p, offset, value) \
759 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
760
761#define READ_INT_FIELD(p, offset) \
762 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
763
764#define WRITE_INT_FIELD(p, offset, value) \
765 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
766
ager@chromium.org3e875802009-06-29 08:26:34 +0000767#define READ_INTPTR_FIELD(p, offset) \
768 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
769
770#define WRITE_INTPTR_FIELD(p, offset, value) \
771 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
772
ager@chromium.org7c537e22008-10-16 08:43:32 +0000773#define READ_UINT32_FIELD(p, offset) \
774 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
775
776#define WRITE_UINT32_FIELD(p, offset, value) \
777 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779#define READ_SHORT_FIELD(p, offset) \
780 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
781
782#define WRITE_SHORT_FIELD(p, offset, value) \
783 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
784
785#define READ_BYTE_FIELD(p, offset) \
786 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
787
788#define WRITE_BYTE_FIELD(p, offset, value) \
789 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
790
791
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000792Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
793 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794}
795
796
797int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000798 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
802Smi* Smi::FromInt(int value) {
803 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000804 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000805 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000806 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000807 return reinterpret_cast<Smi*>(tagged_value);
808}
809
810
811Smi* Smi::FromIntptr(intptr_t value) {
812 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000813 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
814 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815}
816
817
818Failure::Type Failure::type() const {
819 return static_cast<Type>(value() & kFailureTypeTagMask);
820}
821
822
823bool Failure::IsInternalError() const {
824 return type() == INTERNAL_ERROR;
825}
826
827
828bool Failure::IsOutOfMemoryException() const {
829 return type() == OUT_OF_MEMORY_EXCEPTION;
830}
831
832
833int Failure::requested() const {
834 const int kShiftBits =
835 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
836 STATIC_ASSERT(kShiftBits >= 0);
837 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000838 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000839}
840
841
842AllocationSpace Failure::allocation_space() const {
843 ASSERT_EQ(RETRY_AFTER_GC, type());
844 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
845 & kSpaceTagMask);
846}
847
848
849Failure* Failure::InternalError() {
850 return Construct(INTERNAL_ERROR);
851}
852
853
854Failure* Failure::Exception() {
855 return Construct(EXCEPTION);
856}
857
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000858
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859Failure* Failure::OutOfMemoryException() {
860 return Construct(OUT_OF_MEMORY_EXCEPTION);
861}
862
863
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000864intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000865 return static_cast<intptr_t>(
866 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867}
868
869
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000870Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000871 // Assert that the space encoding fits in the three bytes allotted for it.
872 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000873 uintptr_t requested =
874 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
875 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000876 if (((requested << tag_bits) >> tag_bits) != requested) {
877 // No room for entire requested size in the bits. Round down to
878 // maximally representable size.
879 requested = static_cast<intptr_t>(
880 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
881 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000882 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883 return Construct(RETRY_AFTER_GC, value);
884}
885
886
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000887Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000888 uintptr_t info =
889 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000890 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000891 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892}
893
894
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000895bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000896#ifdef DEBUG
897 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
898#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000899
900#ifdef V8_TARGET_ARCH_X64
901 // To be representable as a long smi, the value must be a 32-bit integer.
902 bool result = (value == static_cast<int32_t>(value));
903#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904 // To be representable as an tagged small integer, the two
905 // most-significant bits of 'value' must be either 00 or 11 due to
906 // sign-extension. To check this we add 01 to the two
907 // most-significant bits, and check if the most-significant bit is 0
908 //
909 // CAUTION: The original code below:
910 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
911 // may lead to incorrect results according to the C language spec, and
912 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
913 // compiler may produce undefined results in case of signed integer
914 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000915 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000916#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000917 ASSERT(result == in_range);
918 return result;
919}
920
921
kasper.lund7276f142008-07-30 08:49:36 +0000922MapWord MapWord::FromMap(Map* map) {
923 return MapWord(reinterpret_cast<uintptr_t>(map));
924}
925
926
927Map* MapWord::ToMap() {
928 return reinterpret_cast<Map*>(value_);
929}
930
931
932bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000933 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000934}
935
936
937MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000938 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
939 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000940}
941
942
943HeapObject* MapWord::ToForwardingAddress() {
944 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000945 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000946}
947
948
949bool MapWord::IsMarked() {
950 return (value_ & kMarkingMask) == 0;
951}
952
953
954void MapWord::SetMark() {
955 value_ &= ~kMarkingMask;
956}
957
958
959void MapWord::ClearMark() {
960 value_ |= kMarkingMask;
961}
962
963
964bool MapWord::IsOverflowed() {
965 return (value_ & kOverflowMask) != 0;
966}
967
968
969void MapWord::SetOverflow() {
970 value_ |= kOverflowMask;
971}
972
973
974void MapWord::ClearOverflow() {
975 value_ &= ~kOverflowMask;
976}
977
978
979MapWord MapWord::EncodeAddress(Address map_address, int offset) {
980 // Offset is the distance in live bytes from the first live object in the
981 // same page. The offset between two objects in the same page should not
982 // exceed the object area size of a page.
983 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
984
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000985 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000986 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
987
988 Page* map_page = Page::FromAddress(map_address);
989 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
990
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000991 uintptr_t map_page_offset =
992 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000993
994 uintptr_t encoding =
995 (compact_offset << kForwardingOffsetShift) |
996 (map_page_offset << kMapPageOffsetShift) |
997 (map_page->mc_page_index << kMapPageIndexShift);
998 return MapWord(encoding);
999}
1000
1001
1002Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001003 int map_page_index =
1004 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001005 ASSERT_MAP_PAGE_INDEX(map_page_index);
1006
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001007 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001008 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1009 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001010
1011 return (map_space->PageAddress(map_page_index) + map_page_offset);
1012}
1013
1014
1015int MapWord::DecodeOffset() {
1016 // The offset field is represented in the kForwardingOffsetBits
1017 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001018 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1019 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1020 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001021}
1022
1023
1024MapWord MapWord::FromEncodedAddress(Address address) {
1025 return MapWord(reinterpret_cast<uintptr_t>(address));
1026}
1027
1028
1029Address MapWord::ToEncodedAddress() {
1030 return reinterpret_cast<Address>(value_);
1031}
1032
1033
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001034#ifdef DEBUG
1035void HeapObject::VerifyObjectField(int offset) {
1036 VerifyPointer(READ_FIELD(this, offset));
1037}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001038
1039void HeapObject::VerifySmiField(int offset) {
1040 ASSERT(READ_FIELD(this, offset)->IsSmi());
1041}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042#endif
1043
1044
1045Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001046 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001047}
1048
1049
1050void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001051 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052}
1053
1054
kasper.lund7276f142008-07-30 08:49:36 +00001055MapWord HeapObject::map_word() {
1056 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1057}
1058
1059
1060void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001061 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001062 // here.
1063 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1064}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065
1066
1067HeapObject* HeapObject::FromAddress(Address address) {
1068 ASSERT_TAG_ALIGNED(address);
1069 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1070}
1071
1072
1073Address HeapObject::address() {
1074 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1075}
1076
1077
1078int HeapObject::Size() {
1079 return SizeFromMap(map());
1080}
1081
1082
1083void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1084 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1085 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1086}
1087
1088
1089void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1090 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1091}
1092
1093
kasper.lund7276f142008-07-30 08:49:36 +00001094bool HeapObject::IsMarked() {
1095 return map_word().IsMarked();
1096}
1097
1098
1099void HeapObject::SetMark() {
1100 ASSERT(!IsMarked());
1101 MapWord first_word = map_word();
1102 first_word.SetMark();
1103 set_map_word(first_word);
1104}
1105
1106
1107void HeapObject::ClearMark() {
1108 ASSERT(IsMarked());
1109 MapWord first_word = map_word();
1110 first_word.ClearMark();
1111 set_map_word(first_word);
1112}
1113
1114
1115bool HeapObject::IsOverflowed() {
1116 return map_word().IsOverflowed();
1117}
1118
1119
1120void HeapObject::SetOverflow() {
1121 MapWord first_word = map_word();
1122 first_word.SetOverflow();
1123 set_map_word(first_word);
1124}
1125
1126
1127void HeapObject::ClearOverflow() {
1128 ASSERT(IsOverflowed());
1129 MapWord first_word = map_word();
1130 first_word.ClearOverflow();
1131 set_map_word(first_word);
1132}
1133
1134
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001135double HeapNumber::value() {
1136 return READ_DOUBLE_FIELD(this, kValueOffset);
1137}
1138
1139
1140void HeapNumber::set_value(double value) {
1141 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1142}
1143
1144
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001145int HeapNumber::get_exponent() {
1146 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1147 kExponentShift) - kExponentBias;
1148}
1149
1150
1151int HeapNumber::get_sign() {
1152 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1153}
1154
1155
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001156ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001157
1158
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001159HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001160 Object* array = READ_FIELD(this, kElementsOffset);
1161 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001162 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1163 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001164 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001165}
1166
1167
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001168void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001169 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001170 (value->map() == Heap::fixed_array_map() ||
1171 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001172 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001173 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1174 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001175 WRITE_FIELD(this, kElementsOffset, value);
1176 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1177}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001178
1179
1180void JSObject::initialize_properties() {
1181 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1182 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1183}
1184
1185
1186void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001187 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1189 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1190}
1191
1192
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001193Object* JSObject::ResetElements() {
1194 Object* obj = map()->GetFastElementsMap();
1195 if (obj->IsFailure()) return obj;
1196 set_map(Map::cast(obj));
1197 initialize_elements();
1198 return this;
1199}
1200
1201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202ACCESSORS(Oddball, to_string, String, kToStringOffset)
1203ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1204
1205
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001206Object* JSGlobalPropertyCell::value() {
1207 return READ_FIELD(this, kValueOffset);
1208}
1209
1210
1211void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1212 // The write barrier is not used for global property cells.
1213 ASSERT(!val->IsJSGlobalPropertyCell());
1214 WRITE_FIELD(this, kValueOffset, val);
1215}
1216
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001218int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001219 InstanceType type = map()->instance_type();
1220 // Check for the most common kind of JavaScript object before
1221 // falling into the generic switch. This speeds up the internal
1222 // field operations considerably on average.
1223 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1224 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001225 case JS_GLOBAL_PROXY_TYPE:
1226 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001227 case JS_GLOBAL_OBJECT_TYPE:
1228 return JSGlobalObject::kSize;
1229 case JS_BUILTINS_OBJECT_TYPE:
1230 return JSBuiltinsObject::kSize;
1231 case JS_FUNCTION_TYPE:
1232 return JSFunction::kSize;
1233 case JS_VALUE_TYPE:
1234 return JSValue::kSize;
1235 case JS_ARRAY_TYPE:
1236 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001237 case JS_REGEXP_TYPE:
1238 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001239 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001240 return JSObject::kHeaderSize;
1241 default:
1242 UNREACHABLE();
1243 return 0;
1244 }
1245}
1246
1247
1248int JSObject::GetInternalFieldCount() {
1249 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001250 // Make sure to adjust for the number of in-object properties. These
1251 // properties do contribute to the size, but are not internal fields.
1252 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1253 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001254}
1255
1256
1257Object* JSObject::GetInternalField(int index) {
1258 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001259 // Internal objects do follow immediately after the header, whereas in-object
1260 // properties are at the end of the object. Therefore there is no need
1261 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001262 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1263}
1264
1265
1266void JSObject::SetInternalField(int index, Object* value) {
1267 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001268 // Internal objects do follow immediately after the header, whereas in-object
1269 // properties are at the end of the object. Therefore there is no need
1270 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001271 int offset = GetHeaderSize() + (kPointerSize * index);
1272 WRITE_FIELD(this, offset, value);
1273 WRITE_BARRIER(this, offset);
1274}
1275
1276
ager@chromium.org7c537e22008-10-16 08:43:32 +00001277// Access fast-case object properties at index. The use of these routines
1278// is needed to correctly distinguish between properties stored in-object and
1279// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001280Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001281 // Adjust for the number of properties stored in the object.
1282 index -= map()->inobject_properties();
1283 if (index < 0) {
1284 int offset = map()->instance_size() + (index * kPointerSize);
1285 return READ_FIELD(this, offset);
1286 } else {
1287 ASSERT(index < properties()->length());
1288 return properties()->get(index);
1289 }
1290}
1291
1292
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001293Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001294 // Adjust for the number of properties stored in the object.
1295 index -= map()->inobject_properties();
1296 if (index < 0) {
1297 int offset = map()->instance_size() + (index * kPointerSize);
1298 WRITE_FIELD(this, offset, value);
1299 WRITE_BARRIER(this, offset);
1300 } else {
1301 ASSERT(index < properties()->length());
1302 properties()->set(index, value);
1303 }
1304 return value;
1305}
1306
1307
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001308Object* JSObject::InObjectPropertyAt(int index) {
1309 // Adjust for the number of properties stored in the object.
1310 index -= map()->inobject_properties();
1311 ASSERT(index < 0);
1312 int offset = map()->instance_size() + (index * kPointerSize);
1313 return READ_FIELD(this, offset);
1314}
1315
1316
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001317Object* JSObject::InObjectPropertyAtPut(int index,
1318 Object* value,
1319 WriteBarrierMode mode) {
1320 // Adjust for the number of properties stored in the object.
1321 index -= map()->inobject_properties();
1322 ASSERT(index < 0);
1323 int offset = map()->instance_size() + (index * kPointerSize);
1324 WRITE_FIELD(this, offset, value);
1325 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1326 return value;
1327}
1328
1329
1330
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001332 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001333 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001334 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001335 }
1336}
1337
1338
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001339bool JSObject::HasFastProperties() {
1340 return !properties()->IsDictionary();
1341}
1342
1343
1344int JSObject::MaxFastProperties() {
1345 // Allow extra fast properties if the object has more than
1346 // kMaxFastProperties in-object properties. When this is the case,
1347 // it is very unlikely that the object is being used as a dictionary
1348 // and there is a good chance that allowing more map transitions
1349 // will be worth it.
1350 return Max(map()->inobject_properties(), kMaxFastProperties);
1351}
1352
1353
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001354void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001355 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001356 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001357 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358 }
1359}
1360
1361
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001362bool Object::ToArrayIndex(uint32_t* index) {
1363 if (IsSmi()) {
1364 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001365 if (value < 0) return false;
1366 *index = value;
1367 return true;
1368 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001369 if (IsHeapNumber()) {
1370 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371 uint32_t uint_value = static_cast<uint32_t>(value);
1372 if (value == static_cast<double>(uint_value)) {
1373 *index = uint_value;
1374 return true;
1375 }
1376 }
1377 return false;
1378}
1379
1380
1381bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1382 if (!this->IsJSValue()) return false;
1383
1384 JSValue* js_value = JSValue::cast(this);
1385 if (!js_value->value()->IsString()) return false;
1386
1387 String* str = String::cast(js_value->value());
1388 if (index >= (uint32_t)str->length()) return false;
1389
1390 return true;
1391}
1392
1393
1394Object* FixedArray::get(int index) {
1395 ASSERT(index >= 0 && index < this->length());
1396 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1397}
1398
1399
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001400void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001401 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001402 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1403 int offset = kHeaderSize + index * kPointerSize;
1404 WRITE_FIELD(this, offset, value);
1405}
1406
1407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001409 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410 ASSERT(index >= 0 && index < this->length());
1411 int offset = kHeaderSize + index * kPointerSize;
1412 WRITE_FIELD(this, offset, value);
1413 WRITE_BARRIER(this, offset);
1414}
1415
1416
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001417WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1419 return UPDATE_WRITE_BARRIER;
1420}
1421
1422
1423void FixedArray::set(int index,
1424 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001425 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001426 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427 ASSERT(index >= 0 && index < this->length());
1428 int offset = kHeaderSize + index * kPointerSize;
1429 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001430 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431}
1432
1433
1434void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001435 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001437 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001438 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1439}
1440
1441
1442void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001443 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 ASSERT(index >= 0 && index < this->length());
1445 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1446 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1447 Heap::undefined_value());
1448}
1449
1450
ager@chromium.org236ad962008-09-25 09:45:57 +00001451void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001452 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001453 ASSERT(index >= 0 && index < this->length());
1454 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1455 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1456}
1457
1458
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001460 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 ASSERT(index >= 0 && index < this->length());
1462 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1463 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1464}
1465
1466
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001467void FixedArray::set_unchecked(int index, Smi* value) {
1468 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1469 int offset = kHeaderSize + index * kPointerSize;
1470 WRITE_FIELD(this, offset, value);
1471}
1472
1473
1474void FixedArray::set_null_unchecked(int index) {
1475 ASSERT(index >= 0 && index < this->length());
1476 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1477 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1478}
1479
1480
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001481Object** FixedArray::data_start() {
1482 return HeapObject::RawField(this, kHeaderSize);
1483}
1484
1485
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001486bool DescriptorArray::IsEmpty() {
1487 ASSERT(this == Heap::empty_descriptor_array() ||
1488 this->length() > 2);
1489 return this == Heap::empty_descriptor_array();
1490}
1491
1492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1494 Object* tmp = array->get(first);
1495 fast_set(array, first, array->get(second));
1496 fast_set(array, second, tmp);
1497}
1498
1499
1500int DescriptorArray::Search(String* name) {
1501 SLOW_ASSERT(IsSortedNoDuplicates());
1502
1503 // Check for empty descriptor array.
1504 int nof = number_of_descriptors();
1505 if (nof == 0) return kNotFound;
1506
1507 // Fast case: do linear search for small arrays.
1508 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001509 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001510 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001511 }
1512
1513 // Slow case: perform binary search.
1514 return BinarySearch(name, 0, nof - 1);
1515}
1516
1517
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001518int DescriptorArray::SearchWithCache(String* name) {
1519 int number = DescriptorLookupCache::Lookup(this, name);
1520 if (number == DescriptorLookupCache::kAbsent) {
1521 number = Search(name);
1522 DescriptorLookupCache::Update(this, name, number);
1523 }
1524 return number;
1525}
1526
1527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001528String* DescriptorArray::GetKey(int descriptor_number) {
1529 ASSERT(descriptor_number < number_of_descriptors());
1530 return String::cast(get(ToKeyIndex(descriptor_number)));
1531}
1532
1533
1534Object* DescriptorArray::GetValue(int descriptor_number) {
1535 ASSERT(descriptor_number < number_of_descriptors());
1536 return GetContentArray()->get(ToValueIndex(descriptor_number));
1537}
1538
1539
1540Smi* DescriptorArray::GetDetails(int descriptor_number) {
1541 ASSERT(descriptor_number < number_of_descriptors());
1542 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1543}
1544
1545
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001546PropertyType DescriptorArray::GetType(int descriptor_number) {
1547 ASSERT(descriptor_number < number_of_descriptors());
1548 return PropertyDetails(GetDetails(descriptor_number)).type();
1549}
1550
1551
1552int DescriptorArray::GetFieldIndex(int descriptor_number) {
1553 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1554}
1555
1556
1557JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1558 return JSFunction::cast(GetValue(descriptor_number));
1559}
1560
1561
1562Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1563 ASSERT(GetType(descriptor_number) == CALLBACKS);
1564 return GetValue(descriptor_number);
1565}
1566
1567
1568AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1569 ASSERT(GetType(descriptor_number) == CALLBACKS);
1570 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1571 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1572}
1573
1574
1575bool DescriptorArray::IsProperty(int descriptor_number) {
1576 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1577}
1578
1579
1580bool DescriptorArray::IsTransition(int descriptor_number) {
1581 PropertyType t = GetType(descriptor_number);
1582 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1583}
1584
1585
1586bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1587 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1588}
1589
1590
1591bool DescriptorArray::IsDontEnum(int descriptor_number) {
1592 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1593}
1594
1595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1597 desc->Init(GetKey(descriptor_number),
1598 GetValue(descriptor_number),
1599 GetDetails(descriptor_number));
1600}
1601
1602
1603void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1604 // Range check.
1605 ASSERT(descriptor_number < number_of_descriptors());
1606
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001607 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1609 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1610
1611 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1612 FixedArray* content_array = GetContentArray();
1613 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1614 fast_set(content_array, ToDetailsIndex(descriptor_number),
1615 desc->GetDetails().AsSmi());
1616}
1617
1618
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001619void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1620 Descriptor desc;
1621 src->Get(src_index, &desc);
1622 Set(index, &desc);
1623}
1624
1625
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001626void DescriptorArray::Swap(int first, int second) {
1627 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1628 FixedArray* content_array = GetContentArray();
1629 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1630 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1631}
1632
1633
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001634bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001635 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636 if (!max_index_object->IsSmi()) return false;
1637 return 0 !=
1638 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1639}
1640
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001641uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001642 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001643 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644 if (!max_index_object->IsSmi()) return 0;
1645 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1646 return value >> kRequiresSlowElementsTagSize;
1647}
1648
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001649void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001650 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001651}
1652
1653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654// ------------------------------------
1655// Cast operations
1656
1657
1658CAST_ACCESSOR(FixedArray)
1659CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001660CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001661CAST_ACCESSOR(JSFunctionResultCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001662CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001663CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001664CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001665CAST_ACCESSOR(String)
1666CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001667CAST_ACCESSOR(SeqAsciiString)
1668CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670CAST_ACCESSOR(ExternalString)
1671CAST_ACCESSOR(ExternalAsciiString)
1672CAST_ACCESSOR(ExternalTwoByteString)
1673CAST_ACCESSOR(JSObject)
1674CAST_ACCESSOR(Smi)
1675CAST_ACCESSOR(Failure)
1676CAST_ACCESSOR(HeapObject)
1677CAST_ACCESSOR(HeapNumber)
1678CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001679CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680CAST_ACCESSOR(SharedFunctionInfo)
1681CAST_ACCESSOR(Map)
1682CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001683CAST_ACCESSOR(GlobalObject)
1684CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001685CAST_ACCESSOR(JSGlobalObject)
1686CAST_ACCESSOR(JSBuiltinsObject)
1687CAST_ACCESSOR(Code)
1688CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001689CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690CAST_ACCESSOR(Proxy)
1691CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001692CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001693CAST_ACCESSOR(ExternalArray)
1694CAST_ACCESSOR(ExternalByteArray)
1695CAST_ACCESSOR(ExternalUnsignedByteArray)
1696CAST_ACCESSOR(ExternalShortArray)
1697CAST_ACCESSOR(ExternalUnsignedShortArray)
1698CAST_ACCESSOR(ExternalIntArray)
1699CAST_ACCESSOR(ExternalUnsignedIntArray)
1700CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701CAST_ACCESSOR(Struct)
1702
1703
1704#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1705 STRUCT_LIST(MAKE_STRUCT_CAST)
1706#undef MAKE_STRUCT_CAST
1707
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001708
1709template <typename Shape, typename Key>
1710HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001711 ASSERT(obj->IsHashTable());
1712 return reinterpret_cast<HashTable*>(obj);
1713}
1714
1715
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001716SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1717SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1718
1719INT_ACCESSORS(PixelArray, length, kLengthOffset)
1720INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001721
1722
ager@chromium.orgac091b72010-05-05 07:34:42 +00001723SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001724
1725
1726uint32_t String::hash_field() {
1727 return READ_UINT32_FIELD(this, kHashFieldOffset);
1728}
1729
1730
1731void String::set_hash_field(uint32_t value) {
1732 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001733#if V8_HOST_ARCH_64_BIT
1734 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1735#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001736}
1737
1738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739bool String::Equals(String* other) {
1740 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001741 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1742 return false;
1743 }
1744 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001745}
1746
1747
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001748Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001749 if (!StringShape(this).IsCons()) return this;
1750 ConsString* cons = ConsString::cast(this);
1751 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001752 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753}
1754
1755
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001756String* String::TryFlattenGetString(PretenureFlag pretenure) {
1757 Object* flat = TryFlatten(pretenure);
1758 return flat->IsFailure() ? this : String::cast(flat);
1759}
1760
1761
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001762uint16_t String::Get(int index) {
1763 ASSERT(index >= 0 && index < length());
1764 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001765 case kSeqStringTag | kAsciiStringTag:
1766 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1767 case kSeqStringTag | kTwoByteStringTag:
1768 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1769 case kConsStringTag | kAsciiStringTag:
1770 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001772 case kExternalStringTag | kAsciiStringTag:
1773 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1774 case kExternalStringTag | kTwoByteStringTag:
1775 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 default:
1777 break;
1778 }
1779
1780 UNREACHABLE();
1781 return 0;
1782}
1783
1784
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001785void String::Set(int index, uint16_t value) {
1786 ASSERT(index >= 0 && index < length());
1787 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001788
ager@chromium.org5ec48922009-05-05 07:25:34 +00001789 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001790 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1791 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792}
1793
1794
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001795bool String::IsFlat() {
1796 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001797 case kConsStringTag: {
1798 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001799 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001800 return second->length() == 0;
1801 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001802 default:
1803 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804 }
1805}
1806
1807
ager@chromium.org7c537e22008-10-16 08:43:32 +00001808uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001809 ASSERT(index >= 0 && index < length());
1810 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1811}
1812
1813
ager@chromium.org7c537e22008-10-16 08:43:32 +00001814void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1816 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1817 static_cast<byte>(value));
1818}
1819
1820
ager@chromium.org7c537e22008-10-16 08:43:32 +00001821Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822 return FIELD_ADDR(this, kHeaderSize);
1823}
1824
1825
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001826char* SeqAsciiString::GetChars() {
1827 return reinterpret_cast<char*>(GetCharsAddress());
1828}
1829
1830
ager@chromium.org7c537e22008-10-16 08:43:32 +00001831Address SeqTwoByteString::GetCharsAddress() {
1832 return FIELD_ADDR(this, kHeaderSize);
1833}
1834
1835
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001836uc16* SeqTwoByteString::GetChars() {
1837 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1838}
1839
1840
ager@chromium.org7c537e22008-10-16 08:43:32 +00001841uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001842 ASSERT(index >= 0 && index < length());
1843 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1844}
1845
1846
ager@chromium.org7c537e22008-10-16 08:43:32 +00001847void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848 ASSERT(index >= 0 && index < length());
1849 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1850}
1851
1852
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001853int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001854 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855}
1856
1857
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001858int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001859 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001860}
1861
1862
ager@chromium.org870a0b62008-11-04 11:43:05 +00001863String* ConsString::first() {
1864 return String::cast(READ_FIELD(this, kFirstOffset));
1865}
1866
1867
1868Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869 return READ_FIELD(this, kFirstOffset);
1870}
1871
1872
ager@chromium.org870a0b62008-11-04 11:43:05 +00001873void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001875 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876}
1877
1878
ager@chromium.org870a0b62008-11-04 11:43:05 +00001879String* ConsString::second() {
1880 return String::cast(READ_FIELD(this, kSecondOffset));
1881}
1882
1883
1884Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885 return READ_FIELD(this, kSecondOffset);
1886}
1887
1888
ager@chromium.org870a0b62008-11-04 11:43:05 +00001889void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001891 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001892}
1893
1894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1896 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1897}
1898
1899
1900void ExternalAsciiString::set_resource(
1901 ExternalAsciiString::Resource* resource) {
1902 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1903}
1904
1905
1906ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1907 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1908}
1909
1910
1911void ExternalTwoByteString::set_resource(
1912 ExternalTwoByteString::Resource* resource) {
1913 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1914}
1915
1916
ager@chromium.orgac091b72010-05-05 07:34:42 +00001917void JSFunctionResultCache::MakeZeroSize() {
1918 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1919 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1920}
1921
1922
1923void JSFunctionResultCache::Clear() {
1924 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1925 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1926 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1927 MakeZeroSize();
1928}
1929
1930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931byte ByteArray::get(int index) {
1932 ASSERT(index >= 0 && index < this->length());
1933 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1934}
1935
1936
1937void ByteArray::set(int index, byte value) {
1938 ASSERT(index >= 0 && index < this->length());
1939 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1940}
1941
1942
1943int ByteArray::get_int(int index) {
1944 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1945 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1946}
1947
1948
1949ByteArray* ByteArray::FromDataStartAddress(Address address) {
1950 ASSERT_TAG_ALIGNED(address);
1951 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1952}
1953
1954
1955Address ByteArray::GetDataStartAddress() {
1956 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1957}
1958
1959
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001960uint8_t* PixelArray::external_pointer() {
1961 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1962 return reinterpret_cast<uint8_t*>(ptr);
1963}
1964
1965
1966void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1967 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1968 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1969}
1970
1971
1972uint8_t PixelArray::get(int index) {
1973 ASSERT((index >= 0) && (index < this->length()));
1974 uint8_t* ptr = external_pointer();
1975 return ptr[index];
1976}
1977
1978
1979void PixelArray::set(int index, uint8_t value) {
1980 ASSERT((index >= 0) && (index < this->length()));
1981 uint8_t* ptr = external_pointer();
1982 ptr[index] = value;
1983}
1984
1985
ager@chromium.org3811b432009-10-28 14:53:37 +00001986void* ExternalArray::external_pointer() {
1987 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1988 return reinterpret_cast<void*>(ptr);
1989}
1990
1991
1992void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1993 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1994 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1995}
1996
1997
1998int8_t ExternalByteArray::get(int index) {
1999 ASSERT((index >= 0) && (index < this->length()));
2000 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2001 return ptr[index];
2002}
2003
2004
2005void ExternalByteArray::set(int index, int8_t value) {
2006 ASSERT((index >= 0) && (index < this->length()));
2007 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2008 ptr[index] = value;
2009}
2010
2011
2012uint8_t ExternalUnsignedByteArray::get(int index) {
2013 ASSERT((index >= 0) && (index < this->length()));
2014 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2015 return ptr[index];
2016}
2017
2018
2019void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2020 ASSERT((index >= 0) && (index < this->length()));
2021 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2022 ptr[index] = value;
2023}
2024
2025
2026int16_t ExternalShortArray::get(int index) {
2027 ASSERT((index >= 0) && (index < this->length()));
2028 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2029 return ptr[index];
2030}
2031
2032
2033void ExternalShortArray::set(int index, int16_t value) {
2034 ASSERT((index >= 0) && (index < this->length()));
2035 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2036 ptr[index] = value;
2037}
2038
2039
2040uint16_t ExternalUnsignedShortArray::get(int index) {
2041 ASSERT((index >= 0) && (index < this->length()));
2042 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2043 return ptr[index];
2044}
2045
2046
2047void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2048 ASSERT((index >= 0) && (index < this->length()));
2049 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2050 ptr[index] = value;
2051}
2052
2053
2054int32_t ExternalIntArray::get(int index) {
2055 ASSERT((index >= 0) && (index < this->length()));
2056 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2057 return ptr[index];
2058}
2059
2060
2061void ExternalIntArray::set(int index, int32_t value) {
2062 ASSERT((index >= 0) && (index < this->length()));
2063 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2064 ptr[index] = value;
2065}
2066
2067
2068uint32_t ExternalUnsignedIntArray::get(int index) {
2069 ASSERT((index >= 0) && (index < this->length()));
2070 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2071 return ptr[index];
2072}
2073
2074
2075void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2076 ASSERT((index >= 0) && (index < this->length()));
2077 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2078 ptr[index] = value;
2079}
2080
2081
2082float ExternalFloatArray::get(int index) {
2083 ASSERT((index >= 0) && (index < this->length()));
2084 float* ptr = static_cast<float*>(external_pointer());
2085 return ptr[index];
2086}
2087
2088
2089void ExternalFloatArray::set(int index, float value) {
2090 ASSERT((index >= 0) && (index < this->length()));
2091 float* ptr = static_cast<float*>(external_pointer());
2092 ptr[index] = value;
2093}
2094
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002095
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002096INT_ACCESSORS(Map, visitor_id, kScavengerCallbackOffset)
ager@chromium.org3811b432009-10-28 14:53:37 +00002097
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002099 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2100}
2101
2102
2103int Map::inobject_properties() {
2104 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105}
2106
2107
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002108int Map::pre_allocated_property_fields() {
2109 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2110}
2111
2112
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002113int HeapObject::SizeFromMap(Map* map) {
2114 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002115 // Only inline the most frequent cases.
2116 if (instance_type == JS_OBJECT_TYPE ||
2117 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2118 (kStringTag | kConsStringTag) ||
2119 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002120 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002121 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002123 if (instance_type == BYTE_ARRAY_TYPE) {
2124 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2125 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126 // Otherwise do the general size computation.
2127 return SlowSizeFromMap(map);
2128}
2129
2130
2131void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002132 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002133 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 ASSERT(0 <= value && value < 256);
2135 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2136}
2137
2138
ager@chromium.org7c537e22008-10-16 08:43:32 +00002139void Map::set_inobject_properties(int value) {
2140 ASSERT(0 <= value && value < 256);
2141 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2142}
2143
2144
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002145void Map::set_pre_allocated_property_fields(int value) {
2146 ASSERT(0 <= value && value < 256);
2147 WRITE_BYTE_FIELD(this,
2148 kPreAllocatedPropertyFieldsOffset,
2149 static_cast<byte>(value));
2150}
2151
2152
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153InstanceType Map::instance_type() {
2154 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2155}
2156
2157
2158void Map::set_instance_type(InstanceType value) {
2159 ASSERT(0 <= value && value < 256);
2160 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2161}
2162
2163
2164int Map::unused_property_fields() {
2165 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2166}
2167
2168
2169void Map::set_unused_property_fields(int value) {
2170 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2171}
2172
2173
2174byte Map::bit_field() {
2175 return READ_BYTE_FIELD(this, kBitFieldOffset);
2176}
2177
2178
2179void Map::set_bit_field(byte value) {
2180 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2181}
2182
2183
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002184byte Map::bit_field2() {
2185 return READ_BYTE_FIELD(this, kBitField2Offset);
2186}
2187
2188
2189void Map::set_bit_field2(byte value) {
2190 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2191}
2192
2193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194void Map::set_non_instance_prototype(bool value) {
2195 if (value) {
2196 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2197 } else {
2198 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2199 }
2200}
2201
2202
2203bool Map::has_non_instance_prototype() {
2204 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2205}
2206
2207
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002208void Map::set_function_with_prototype(bool value) {
2209 if (value) {
2210 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2211 } else {
2212 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2213 }
2214}
2215
2216
2217bool Map::function_with_prototype() {
2218 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2219}
2220
2221
ager@chromium.org870a0b62008-11-04 11:43:05 +00002222void Map::set_is_access_check_needed(bool access_check_needed) {
2223 if (access_check_needed) {
2224 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2225 } else {
2226 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2227 }
2228}
2229
2230
2231bool Map::is_access_check_needed() {
2232 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2233}
2234
2235
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002236void Map::set_is_extensible(bool value) {
2237 if (value) {
2238 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2239 } else {
2240 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2241 }
2242}
2243
2244bool Map::is_extensible() {
2245 return ((1 << kIsExtensible) & bit_field2()) != 0;
2246}
2247
2248
2249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002250Code::Flags Code::flags() {
2251 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2252}
2253
2254
2255void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002256 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002258 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2259 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260 ExtractArgumentsCountFromFlags(flags) >= 0);
2261 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2262}
2263
2264
2265Code::Kind Code::kind() {
2266 return ExtractKindFromFlags(flags());
2267}
2268
2269
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002270InLoopFlag Code::ic_in_loop() {
2271 return ExtractICInLoopFromFlags(flags());
2272}
2273
2274
kasper.lund7276f142008-07-30 08:49:36 +00002275InlineCacheState Code::ic_state() {
2276 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002277 // Only allow uninitialized or debugger states for non-IC code
2278 // objects. This is used in the debugger to determine whether or not
2279 // a call to code object has been replaced with a debug break call.
2280 ASSERT(is_inline_cache_stub() ||
2281 result == UNINITIALIZED ||
2282 result == DEBUG_BREAK ||
2283 result == DEBUG_PREPARE_STEP_IN);
2284 return result;
2285}
2286
2287
2288PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002289 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290 return ExtractTypeFromFlags(flags());
2291}
2292
2293
2294int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002295 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002296 return ExtractArgumentsCountFromFlags(flags());
2297}
2298
2299
2300CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002301 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002302 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2303 kStubMajorKeyOffset));
2304}
2305
2306
2307void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002308 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002309 ASSERT(0 <= major && major < 256);
2310 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002311}
2312
2313
2314bool Code::is_inline_cache_stub() {
2315 Kind kind = this->kind();
2316 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2317}
2318
2319
2320Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002321 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002322 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002323 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002324 int argc,
2325 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326 // Compute the bit mask.
2327 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002328 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002329 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330 bits |= type << kFlagsTypeShift;
2331 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002332 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 // Cast to flags and validate result before returning it.
2334 Flags result = static_cast<Flags>(bits);
2335 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002336 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002337 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338 ASSERT(ExtractTypeFromFlags(result) == type);
2339 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2340 return result;
2341}
2342
2343
2344Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2345 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002346 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002347 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002349 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350}
2351
2352
2353Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2354 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2355 return static_cast<Kind>(bits);
2356}
2357
2358
kasper.lund7276f142008-07-30 08:49:36 +00002359InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2360 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361 return static_cast<InlineCacheState>(bits);
2362}
2363
2364
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002365InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2366 int bits = (flags & kFlagsICInLoopMask);
2367 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2368}
2369
2370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2372 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2373 return static_cast<PropertyType>(bits);
2374}
2375
2376
2377int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2378 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2379}
2380
2381
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002382InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2383 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2384 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2385}
2386
2387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2389 int bits = flags & ~kFlagsTypeMask;
2390 return static_cast<Flags>(bits);
2391}
2392
2393
ager@chromium.org8bb60582008-12-11 12:02:20 +00002394Code* Code::GetCodeFromTargetAddress(Address address) {
2395 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2396 // GetCodeFromTargetAddress might be called when marking objects during mark
2397 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2398 // Code::cast. Code::cast does not work when the object's map is
2399 // marked.
2400 Code* result = reinterpret_cast<Code*>(code);
2401 return result;
2402}
2403
2404
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405Object* Map::prototype() {
2406 return READ_FIELD(this, kPrototypeOffset);
2407}
2408
2409
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002410void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 ASSERT(value->IsNull() || value->IsJSObject());
2412 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002413 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414}
2415
2416
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002417Object* Map::GetFastElementsMap() {
2418 if (has_fast_elements()) return this;
2419 Object* obj = CopyDropTransitions();
2420 if (obj->IsFailure()) return obj;
2421 Map* new_map = Map::cast(obj);
2422 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002423 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002424 return new_map;
2425}
2426
2427
2428Object* Map::GetSlowElementsMap() {
2429 if (!has_fast_elements()) return this;
2430 Object* obj = CopyDropTransitions();
2431 if (obj->IsFailure()) return obj;
2432 Map* new_map = Map::cast(obj);
2433 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002434 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002435 return new_map;
2436}
2437
2438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439ACCESSORS(Map, instance_descriptors, DescriptorArray,
2440 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002441ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442ACCESSORS(Map, constructor, Object, kConstructorOffset)
2443
2444ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2445ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2446
2447ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2448ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002449ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002450
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002451ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002452
2453ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2454ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2455ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2456ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2457ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002458ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459
2460ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2461ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2462ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2463
2464ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2465ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2466ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2467ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2468ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2469ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2470
2471ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2472ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2473
2474ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2475ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2476
2477ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2478ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002479ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2480 kPropertyAccessorsOffset)
2481ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2482 kPrototypeTemplateOffset)
2483ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2484ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2485 kNamedPropertyHandlerOffset)
2486ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2487 kIndexedPropertyHandlerOffset)
2488ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2489 kInstanceTemplateOffset)
2490ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2491ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002492ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2493 kInstanceCallHandlerOffset)
2494ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2495 kAccessCheckInfoOffset)
2496ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2497
2498ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002499ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2500 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002501
2502ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2503ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2504
2505ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2506
2507ACCESSORS(Script, source, Object, kSourceOffset)
2508ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002509ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002510ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2511ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002512ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002513ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002514ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2515ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002516ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002517ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002518ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002519ACCESSORS(Script, eval_from_instructions_offset, Smi,
2520 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002521
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002522#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002523ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2524ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2525ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2526ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2527
2528ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2529ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2530ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2531ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002532#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002533
2534ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002535ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2537 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002538ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2540ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002541ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002542ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2543 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002544
2545BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2546 kHiddenPrototypeBit)
2547BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2548BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2549 kNeedsAccessCheckBit)
2550BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2551 kIsExpressionBit)
2552BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2553 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002554BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002555 has_only_simple_this_property_assignments,
2556 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002557BOOL_ACCESSORS(SharedFunctionInfo,
2558 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002559 try_full_codegen,
2560 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002561BOOL_ACCESSORS(SharedFunctionInfo,
2562 compiler_hints,
2563 allows_lazy_compilation,
2564 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002565
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002566
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002567#if V8_HOST_ARCH_32_BIT
2568SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2569SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002570 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002571SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002572 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002573SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2574SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002576SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2577SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002578 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002579SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002580 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002581SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002582 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002583#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002584
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002585#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2586 int holder::name() { \
2587 int value = READ_INT_FIELD(this, offset); \
2588 ASSERT(kHeapObjectTag == 1); \
2589 ASSERT((value & kHeapObjectTag) == 0); \
2590 return value >> 1; \
2591 } \
2592 void holder::set_##name(int value) { \
2593 ASSERT(kHeapObjectTag == 1); \
2594 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2595 (value & 0xC0000000) == 0x000000000); \
2596 WRITE_INT_FIELD(this, \
2597 offset, \
2598 (value << 1) & ~kHeapObjectTag); \
2599 }
2600
2601#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2602 INT_ACCESSORS(holder, name, offset)
2603
2604
2605
2606PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2607PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2608 kFormalParameterCountOffset)
2609
2610PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2611 kExpectedNofPropertiesOffset)
2612PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2613
2614PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2615 kStartPositionAndTypeOffset)
2616PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2617
2618PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2619 kFunctionTokenPositionOffset)
2620PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2621 kCompilerHintsOffset)
2622
2623PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2624 kThisPropertyAssignmentsCountOffset)
2625#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002626
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002627ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2628ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2629
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002630bool Script::HasValidSource() {
2631 Object* src = this->source();
2632 if (!src->IsString()) return true;
2633 String* src_str = String::cast(src);
2634 if (!StringShape(src_str).IsExternal()) return true;
2635 if (src_str->IsAsciiRepresentation()) {
2636 return ExternalAsciiString::cast(src)->resource() != NULL;
2637 } else if (src_str->IsTwoByteRepresentation()) {
2638 return ExternalTwoByteString::cast(src)->resource() != NULL;
2639 }
2640 return true;
2641}
2642
2643
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002644void SharedFunctionInfo::DontAdaptArguments() {
2645 ASSERT(code()->kind() == Code::BUILTIN);
2646 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2647}
2648
2649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002650int SharedFunctionInfo::start_position() {
2651 return start_position_and_type() >> kStartPositionShift;
2652}
2653
2654
2655void SharedFunctionInfo::set_start_position(int start_position) {
2656 set_start_position_and_type((start_position << kStartPositionShift)
2657 | (start_position_and_type() & ~kStartPositionMask));
2658}
2659
2660
2661Code* SharedFunctionInfo::code() {
2662 return Code::cast(READ_FIELD(this, kCodeOffset));
2663}
2664
2665
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002666Code* SharedFunctionInfo::unchecked_code() {
2667 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2668}
2669
2670
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002671void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002673 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002674}
2675
2676
ager@chromium.orgb5737492010-07-15 09:29:43 +00002677SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2678 return reinterpret_cast<SerializedScopeInfo*>(
2679 READ_FIELD(this, kScopeInfoOffset));
2680}
2681
2682
2683void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2684 WriteBarrierMode mode) {
2685 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2686 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2687}
2688
2689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002690bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002691 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002692}
2693
2694
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002695bool SharedFunctionInfo::IsApiFunction() {
2696 return function_data()->IsFunctionTemplateInfo();
2697}
2698
2699
2700FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2701 ASSERT(IsApiFunction());
2702 return FunctionTemplateInfo::cast(function_data());
2703}
2704
2705
2706bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002707 return function_data()->IsSmi();
2708}
2709
2710
2711int SharedFunctionInfo::custom_call_generator_id() {
2712 ASSERT(HasCustomCallGenerator());
2713 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002714}
2715
2716
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002717int SharedFunctionInfo::code_age() {
2718 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2719}
2720
2721
2722void SharedFunctionInfo::set_code_age(int code_age) {
2723 set_compiler_hints(compiler_hints() |
2724 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2725}
2726
2727
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002728bool JSFunction::IsBuiltin() {
2729 return context()->global()->IsJSBuiltinsObject();
2730}
2731
2732
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733Code* JSFunction::code() {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002734 return Code::cast(READ_FIELD(this, kCodeOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002735}
2736
2737
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002738Code* JSFunction::unchecked_code() {
2739 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2740}
2741
2742
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002743void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002744 // Skip the write barrier because code is never in new space.
2745 ASSERT(!Heap::InNewSpace(value));
2746 WRITE_FIELD(this, kCodeOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002747}
2748
2749
2750Context* JSFunction::context() {
2751 return Context::cast(READ_FIELD(this, kContextOffset));
2752}
2753
2754
2755Object* JSFunction::unchecked_context() {
2756 return READ_FIELD(this, kContextOffset);
2757}
2758
2759
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002760SharedFunctionInfo* JSFunction::unchecked_shared() {
2761 return reinterpret_cast<SharedFunctionInfo*>(
2762 READ_FIELD(this, kSharedFunctionInfoOffset));
2763}
2764
2765
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766void JSFunction::set_context(Object* value) {
2767 ASSERT(value == Heap::undefined_value() || value->IsContext());
2768 WRITE_FIELD(this, kContextOffset, value);
2769 WRITE_BARRIER(this, kContextOffset);
2770}
2771
2772ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2773 kPrototypeOrInitialMapOffset)
2774
2775
2776Map* JSFunction::initial_map() {
2777 return Map::cast(prototype_or_initial_map());
2778}
2779
2780
2781void JSFunction::set_initial_map(Map* value) {
2782 set_prototype_or_initial_map(value);
2783}
2784
2785
2786bool JSFunction::has_initial_map() {
2787 return prototype_or_initial_map()->IsMap();
2788}
2789
2790
2791bool JSFunction::has_instance_prototype() {
2792 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2793}
2794
2795
2796bool JSFunction::has_prototype() {
2797 return map()->has_non_instance_prototype() || has_instance_prototype();
2798}
2799
2800
2801Object* JSFunction::instance_prototype() {
2802 ASSERT(has_instance_prototype());
2803 if (has_initial_map()) return initial_map()->prototype();
2804 // When there is no initial map and the prototype is a JSObject, the
2805 // initial map field is used for the prototype field.
2806 return prototype_or_initial_map();
2807}
2808
2809
2810Object* JSFunction::prototype() {
2811 ASSERT(has_prototype());
2812 // If the function's prototype property has been set to a non-JSObject
2813 // value, that value is stored in the constructor field of the map.
2814 if (map()->has_non_instance_prototype()) return map()->constructor();
2815 return instance_prototype();
2816}
2817
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002818bool JSFunction::should_have_prototype() {
2819 return map()->function_with_prototype();
2820}
2821
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002822
2823bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002824 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825}
2826
2827
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002828int JSFunction::NumberOfLiterals() {
2829 return literals()->length();
2830}
2831
2832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2834 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002835 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836}
2837
2838
2839void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2840 Object* value) {
2841 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002842 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2843 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2844}
2845
2846
2847Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2848 ASSERT(0 <= id && id < kJSBuiltinsCount);
2849 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2850}
2851
2852
2853void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2854 Code* value) {
2855 ASSERT(0 <= id && id < kJSBuiltinsCount);
2856 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2857 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858}
2859
2860
2861Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002862 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863}
2864
2865
2866void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002867 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002868}
2869
2870
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002871ACCESSORS(JSValue, value, Object, kValueOffset)
2872
2873
2874JSValue* JSValue::cast(Object* obj) {
2875 ASSERT(obj->IsJSValue());
2876 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2877 return reinterpret_cast<JSValue*>(obj);
2878}
2879
2880
2881INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002882ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002883
2884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885byte* Code::instruction_start() {
2886 return FIELD_ADDR(this, kHeaderSize);
2887}
2888
2889
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002890byte* Code::instruction_end() {
2891 return instruction_start() + instruction_size();
2892}
2893
2894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002895int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002896 return RoundUp(instruction_size(), kObjectAlignment);
2897}
2898
2899
2900ByteArray* Code::unchecked_relocation_info() {
2901 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902}
2903
2904
2905byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002906 return unchecked_relocation_info()->GetDataStartAddress();
2907}
2908
2909
2910int Code::relocation_size() {
2911 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912}
2913
2914
2915byte* Code::entry() {
2916 return instruction_start();
2917}
2918
2919
2920bool Code::contains(byte* pc) {
2921 return (instruction_start() <= pc) &&
2922 (pc < instruction_start() + instruction_size());
2923}
2924
2925
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926ACCESSORS(JSArray, length, Object, kLengthOffset)
2927
2928
ager@chromium.org236ad962008-09-25 09:45:57 +00002929ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002930
2931
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002932JSRegExp::Type JSRegExp::TypeTag() {
2933 Object* data = this->data();
2934 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2935 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2936 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002937}
2938
2939
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002940int JSRegExp::CaptureCount() {
2941 switch (TypeTag()) {
2942 case ATOM:
2943 return 0;
2944 case IRREGEXP:
2945 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2946 default:
2947 UNREACHABLE();
2948 return -1;
2949 }
2950}
2951
2952
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002953JSRegExp::Flags JSRegExp::GetFlags() {
2954 ASSERT(this->data()->IsFixedArray());
2955 Object* data = this->data();
2956 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2957 return Flags(smi->value());
2958}
2959
2960
2961String* JSRegExp::Pattern() {
2962 ASSERT(this->data()->IsFixedArray());
2963 Object* data = this->data();
2964 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2965 return pattern;
2966}
2967
2968
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002969Object* JSRegExp::DataAt(int index) {
2970 ASSERT(TypeTag() != NOT_COMPILED);
2971 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002972}
2973
2974
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002975void JSRegExp::SetDataAt(int index, Object* value) {
2976 ASSERT(TypeTag() != NOT_COMPILED);
2977 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2978 FixedArray::cast(data())->set(index, value);
2979}
2980
2981
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002982JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002983 if (map()->has_fast_elements()) {
2984 ASSERT(elements()->map() == Heap::fixed_array_map() ||
2985 elements()->map() == Heap::fixed_cow_array_map());
2986 return FAST_ELEMENTS;
2987 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002988 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002989 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002990 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
2991 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002992 ASSERT(array->IsDictionary());
2993 return DICTIONARY_ELEMENTS;
2994 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002995 if (array->IsExternalArray()) {
2996 switch (array->map()->instance_type()) {
2997 case EXTERNAL_BYTE_ARRAY_TYPE:
2998 return EXTERNAL_BYTE_ELEMENTS;
2999 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3000 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3001 case EXTERNAL_SHORT_ARRAY_TYPE:
3002 return EXTERNAL_SHORT_ELEMENTS;
3003 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3004 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3005 case EXTERNAL_INT_ARRAY_TYPE:
3006 return EXTERNAL_INT_ELEMENTS;
3007 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3008 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3009 default:
3010 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3011 return EXTERNAL_FLOAT_ELEMENTS;
3012 }
3013 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003014 ASSERT(array->IsPixelArray());
3015 return PIXEL_ELEMENTS;
3016}
3017
3018
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003019bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003020 return GetElementsKind() == FAST_ELEMENTS;
3021}
3022
3023
3024bool JSObject::HasDictionaryElements() {
3025 return GetElementsKind() == DICTIONARY_ELEMENTS;
3026}
3027
3028
3029bool JSObject::HasPixelElements() {
3030 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003031}
3032
3033
ager@chromium.org3811b432009-10-28 14:53:37 +00003034bool JSObject::HasExternalArrayElements() {
3035 return (HasExternalByteElements() ||
3036 HasExternalUnsignedByteElements() ||
3037 HasExternalShortElements() ||
3038 HasExternalUnsignedShortElements() ||
3039 HasExternalIntElements() ||
3040 HasExternalUnsignedIntElements() ||
3041 HasExternalFloatElements());
3042}
3043
3044
3045bool JSObject::HasExternalByteElements() {
3046 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3047}
3048
3049
3050bool JSObject::HasExternalUnsignedByteElements() {
3051 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3052}
3053
3054
3055bool JSObject::HasExternalShortElements() {
3056 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3057}
3058
3059
3060bool JSObject::HasExternalUnsignedShortElements() {
3061 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3062}
3063
3064
3065bool JSObject::HasExternalIntElements() {
3066 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3067}
3068
3069
3070bool JSObject::HasExternalUnsignedIntElements() {
3071 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3072}
3073
3074
3075bool JSObject::HasExternalFloatElements() {
3076 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3077}
3078
3079
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003080bool JSObject::HasNamedInterceptor() {
3081 return map()->has_named_interceptor();
3082}
3083
3084
3085bool JSObject::HasIndexedInterceptor() {
3086 return map()->has_indexed_interceptor();
3087}
3088
3089
ager@chromium.org5c838252010-02-19 08:53:10 +00003090bool JSObject::AllowsSetElementsLength() {
3091 bool result = elements()->IsFixedArray();
3092 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3093 return result;
3094}
3095
3096
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003097Object* JSObject::EnsureWritableFastElements() {
3098 ASSERT(HasFastElements());
3099 FixedArray* elems = FixedArray::cast(elements());
3100 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
3101 Object* writable_elems = Heap::CopyFixedArray(elems);
3102 if (writable_elems->IsFailure()) return writable_elems;
3103 FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
3104 set_elements(FixedArray::cast(writable_elems));
3105 Counters::cow_arrays_converted.Increment();
3106 return writable_elems;
3107}
3108
3109
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003110StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003112 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003113}
3114
3115
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003116NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003117 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003118 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003119}
3120
3121
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003122bool String::IsHashFieldComputed(uint32_t field) {
3123 return (field & kHashNotComputedMask) == 0;
3124}
3125
3126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003127bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003128 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003129}
3130
3131
3132uint32_t String::Hash() {
3133 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003134 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003135 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003136 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003137 return ComputeAndSetHash();
3138}
3139
3140
ager@chromium.org7c537e22008-10-16 08:43:32 +00003141StringHasher::StringHasher(int length)
3142 : length_(length),
3143 raw_running_hash_(0),
3144 array_index_(0),
3145 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3146 is_first_char_(true),
3147 is_valid_(true) { }
3148
3149
3150bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003151 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003152}
3153
3154
3155void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003156 // Use the Jenkins one-at-a-time hash function to update the hash
3157 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003158 raw_running_hash_ += c;
3159 raw_running_hash_ += (raw_running_hash_ << 10);
3160 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003161 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003162 if (is_array_index_) {
3163 if (c < '0' || c > '9') {
3164 is_array_index_ = false;
3165 } else {
3166 int d = c - '0';
3167 if (is_first_char_) {
3168 is_first_char_ = false;
3169 if (c == '0' && length_ > 1) {
3170 is_array_index_ = false;
3171 return;
3172 }
3173 }
3174 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3175 is_array_index_ = false;
3176 } else {
3177 array_index_ = array_index_ * 10 + d;
3178 }
3179 }
3180 }
3181}
3182
3183
3184void StringHasher::AddCharacterNoIndex(uc32 c) {
3185 ASSERT(!is_array_index());
3186 raw_running_hash_ += c;
3187 raw_running_hash_ += (raw_running_hash_ << 10);
3188 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3189}
3190
3191
3192uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003193 // Get the calculated raw hash value and do some more bit ops to distribute
3194 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003195 uint32_t result = raw_running_hash_;
3196 result += (result << 3);
3197 result ^= (result >> 11);
3198 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003199 if (result == 0) {
3200 result = 27;
3201 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003202 return result;
3203}
3204
3205
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003207 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003208 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3209 return false;
3210 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211 return SlowAsArrayIndex(index);
3212}
3213
3214
3215Object* JSObject::GetPrototype() {
3216 return JSObject::cast(this)->map()->prototype();
3217}
3218
3219
3220PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3221 return GetPropertyAttributeWithReceiver(this, key);
3222}
3223
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003224// TODO(504): this may be useful in other places too where JSGlobalProxy
3225// is used.
3226Object* JSObject::BypassGlobalProxy() {
3227 if (IsJSGlobalProxy()) {
3228 Object* proto = GetPrototype();
3229 if (proto->IsNull()) return Heap::undefined_value();
3230 ASSERT(proto->IsJSGlobalObject());
3231 return proto;
3232 }
3233 return this;
3234}
3235
3236
3237bool JSObject::HasHiddenPropertiesObject() {
3238 ASSERT(!IsJSGlobalProxy());
3239 return GetPropertyAttributePostInterceptor(this,
3240 Heap::hidden_symbol(),
3241 false) != ABSENT;
3242}
3243
3244
3245Object* JSObject::GetHiddenPropertiesObject() {
3246 ASSERT(!IsJSGlobalProxy());
3247 PropertyAttributes attributes;
3248 return GetLocalPropertyPostInterceptor(this,
3249 Heap::hidden_symbol(),
3250 &attributes);
3251}
3252
3253
3254Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3255 ASSERT(!IsJSGlobalProxy());
3256 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3257 hidden_obj,
3258 DONT_ENUM);
3259}
3260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261
3262bool JSObject::HasElement(uint32_t index) {
3263 return HasElementWithReceiver(this, index);
3264}
3265
3266
3267bool AccessorInfo::all_can_read() {
3268 return BooleanBit::get(flag(), kAllCanReadBit);
3269}
3270
3271
3272void AccessorInfo::set_all_can_read(bool value) {
3273 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3274}
3275
3276
3277bool AccessorInfo::all_can_write() {
3278 return BooleanBit::get(flag(), kAllCanWriteBit);
3279}
3280
3281
3282void AccessorInfo::set_all_can_write(bool value) {
3283 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3284}
3285
3286
ager@chromium.org870a0b62008-11-04 11:43:05 +00003287bool AccessorInfo::prohibits_overwriting() {
3288 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3289}
3290
3291
3292void AccessorInfo::set_prohibits_overwriting(bool value) {
3293 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3294}
3295
3296
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297PropertyAttributes AccessorInfo::property_attributes() {
3298 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3299}
3300
3301
3302void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3303 ASSERT(AttributesField::is_valid(attributes));
3304 int rest_value = flag()->value() & ~AttributesField::mask();
3305 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3306}
3307
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003308template<typename Shape, typename Key>
3309void Dictionary<Shape, Key>::SetEntry(int entry,
3310 Object* key,
3311 Object* value,
3312 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003313 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003314 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003315 AssertNoAllocation no_gc;
3316 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003317 FixedArray::set(index, key, mode);
3318 FixedArray::set(index+1, value, mode);
3319 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320}
3321
3322
3323void Map::ClearCodeCache() {
3324 // No write barrier is needed since empty_fixed_array is not in new space.
3325 // Please note this function is used during marking:
3326 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003327 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3328 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329}
3330
3331
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003332void JSArray::EnsureSize(int required_size) {
3333 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003334 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003335 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3336 if (elts->length() < required_size) {
3337 // Doubling in size would be overkill, but leave some slack to avoid
3338 // constantly growing.
3339 Expand(required_size + (required_size >> 3));
3340 // It's a performance benefit to keep a frequently used array in new-space.
3341 } else if (!Heap::new_space()->Contains(elts) &&
3342 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3343 // Expand will allocate a new backing store in new space even if the size
3344 // we asked for isn't larger than what we had before.
3345 Expand(required_size);
3346 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003347}
3348
3349
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003350void JSArray::set_length(Smi* length) {
3351 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3352}
3353
3354
ager@chromium.org7c537e22008-10-16 08:43:32 +00003355void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003356 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003357 set_elements(storage);
3358}
3359
3360
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003361Object* FixedArray::Copy() {
3362 if (length() == 0) return this;
3363 return Heap::CopyFixedArray(this);
3364}
3365
3366
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003367int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3368 return map->instance_size();
3369}
3370
3371
3372void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3373 v->VisitExternalReference(
3374 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3375}
3376
3377
3378template<typename StaticVisitor>
3379void Proxy::ProxyIterateBody() {
3380 StaticVisitor::VisitExternalReference(
3381 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3382}
3383
3384
3385void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3386 typedef v8::String::ExternalAsciiStringResource Resource;
3387 v->VisitExternalAsciiString(
3388 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3389}
3390
3391
3392template<typename StaticVisitor>
3393void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3394 typedef v8::String::ExternalAsciiStringResource Resource;
3395 StaticVisitor::VisitExternalAsciiString(
3396 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3397}
3398
3399
3400void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3401 typedef v8::String::ExternalStringResource Resource;
3402 v->VisitExternalTwoByteString(
3403 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3404}
3405
3406
3407template<typename StaticVisitor>
3408void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3409 typedef v8::String::ExternalStringResource Resource;
3410 StaticVisitor::VisitExternalTwoByteString(
3411 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3412}
3413
3414#define SLOT_ADDR(obj, offset) \
3415 reinterpret_cast<Object**>((obj)->address() + offset)
3416
3417template<int start_offset, int end_offset, int size>
3418void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3419 HeapObject* obj,
3420 ObjectVisitor* v) {
3421 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3422}
3423
3424
3425template<int start_offset>
3426void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3427 int object_size,
3428 ObjectVisitor* v) {
3429 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3430}
3431
3432#undef SLOT_ADDR
3433
3434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003435#undef CAST_ACCESSOR
3436#undef INT_ACCESSORS
3437#undef SMI_ACCESSORS
3438#undef ACCESSORS
3439#undef FIELD_ADDR
3440#undef READ_FIELD
3441#undef WRITE_FIELD
3442#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003443#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444#undef READ_MEMADDR_FIELD
3445#undef WRITE_MEMADDR_FIELD
3446#undef READ_DOUBLE_FIELD
3447#undef WRITE_DOUBLE_FIELD
3448#undef READ_INT_FIELD
3449#undef WRITE_INT_FIELD
3450#undef READ_SHORT_FIELD
3451#undef WRITE_SHORT_FIELD
3452#undef READ_BYTE_FIELD
3453#undef WRITE_BYTE_FIELD
3454
3455
3456} } // namespace v8::internal
3457
3458#endif // V8_OBJECTS_INL_H_