blob: 0ef39fcd70c4fe34a1da937a2c17a0247eb72774 [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
erik.corry@gmail.com145eff52010-08-23 11:36:18 +000038#include "memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
erik.corry@gmail.com145eff52010-08-23 11:36:18 +000041#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042#include "property.h"
43
kasperl@chromium.org71affb52009-05-26 05:44:31 +000044namespace v8 {
45namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
47PropertyDetails::PropertyDetails(Smi* smi) {
48 value_ = smi->value();
49}
50
51
52Smi* PropertyDetails::AsSmi() {
53 return Smi::FromInt(value_);
54}
55
56
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000057PropertyDetails PropertyDetails::AsDeleted() {
58 PropertyDetails d(DONT_ENUM, NORMAL);
59 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
60 return PropertyDetails(smi);
61}
62
63
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000064#define CAST_ACCESSOR(type) \
65 type* type::cast(Object* object) { \
66 ASSERT(object->Is##type()); \
67 return reinterpret_cast<type*>(object); \
68 }
69
70
71#define INT_ACCESSORS(holder, name, offset) \
72 int holder::name() { return READ_INT_FIELD(this, offset); } \
73 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
74
75
76#define ACCESSORS(holder, name, type, offset) \
77 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000078 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000079 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 }
82
83
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000084
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085#define SMI_ACCESSORS(holder, name, offset) \
86 int holder::name() { \
87 Object* value = READ_FIELD(this, offset); \
88 return Smi::cast(value)->value(); \
89 } \
90 void holder::set_##name(int value) { \
91 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
92 }
93
94
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000095#define BOOL_GETTER(holder, field, name, offset) \
96 bool holder::name() { \
97 return BooleanBit::get(field(), offset); \
98 } \
99
100
101#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000102 bool holder::name() { \
103 return BooleanBit::get(field(), offset); \
104 } \
105 void holder::set_##name(bool value) { \
106 set_##field(BooleanBit::set(field(), offset, value)); \
107 }
108
109
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000110bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
111 // There is a constraint on the object; check.
112 if (!this->IsJSObject()) return false;
113 // Fetch the constructor function of the object.
114 Object* cons_obj = JSObject::cast(this)->map()->constructor();
115 if (!cons_obj->IsJSFunction()) return false;
116 JSFunction* fun = JSFunction::cast(cons_obj);
117 // Iterate through the chain of inheriting function templates to
118 // see if the required one occurs.
119 for (Object* type = fun->shared()->function_data();
120 type->IsFunctionTemplateInfo();
121 type = FunctionTemplateInfo::cast(type)->parent_template()) {
122 if (type == expected) return true;
123 }
124 // Didn't find the required type in the inheritance chain.
125 return false;
126}
127
128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000129bool Object::IsSmi() {
130 return HAS_SMI_TAG(this);
131}
132
133
134bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000135 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000136}
137
138
139bool Object::IsHeapNumber() {
140 return Object::IsHeapObject()
141 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
142}
143
144
145bool Object::IsString() {
146 return Object::IsHeapObject()
147 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
148}
149
150
ager@chromium.org870a0b62008-11-04 11:43:05 +0000151bool Object::IsSymbol() {
152 if (!this->IsHeapObject()) return false;
153 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000154 // Because the symbol tag is non-zero and no non-string types have the
155 // symbol bit set we can test for symbols with a very simple test
156 // operation.
157 ASSERT(kSymbolTag != 0);
158 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
159 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000160}
161
162
163bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000164 if (!this->IsHeapObject()) return false;
165 uint32_t type = HeapObject::cast(this)->map()->instance_type();
166 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
167 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000168}
169
170
ager@chromium.org870a0b62008-11-04 11:43:05 +0000171bool Object::IsSeqString() {
172 if (!IsString()) return false;
173 return StringShape(String::cast(this)).IsSequential();
174}
175
176
177bool Object::IsSeqAsciiString() {
178 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000179 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000180 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181}
182
183
184bool Object::IsSeqTwoByteString() {
185 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000186 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000187 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000188}
189
190
191bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000192 if (!IsString()) return false;
193 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194}
195
196
197bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000198 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000199 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000200 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201}
202
203
204bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000205 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000206 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000207 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208}
209
210
ager@chromium.org870a0b62008-11-04 11:43:05 +0000211StringShape::StringShape(String* str)
212 : type_(str->map()->instance_type()) {
213 set_valid();
214 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215}
216
217
ager@chromium.org870a0b62008-11-04 11:43:05 +0000218StringShape::StringShape(Map* map)
219 : type_(map->instance_type()) {
220 set_valid();
221 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222}
223
224
ager@chromium.org870a0b62008-11-04 11:43:05 +0000225StringShape::StringShape(InstanceType t)
226 : type_(static_cast<uint32_t>(t)) {
227 set_valid();
228 ASSERT((type_ & kIsNotStringMask) == kStringTag);
229}
230
231
232bool StringShape::IsSymbol() {
233 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000234 ASSERT(kSymbolTag != 0);
235 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000236}
237
238
ager@chromium.org5ec48922009-05-05 07:25:34 +0000239bool String::IsAsciiRepresentation() {
240 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000241 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242}
243
244
ager@chromium.org5ec48922009-05-05 07:25:34 +0000245bool String::IsTwoByteRepresentation() {
246 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000247 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000248}
249
250
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000251bool String::HasOnlyAsciiChars() {
252 uint32_t type = map()->instance_type();
253 return (type & kStringEncodingMask) == kAsciiStringTag ||
254 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000255}
256
257
ager@chromium.org870a0b62008-11-04 11:43:05 +0000258bool StringShape::IsCons() {
259 return (type_ & kStringRepresentationMask) == kConsStringTag;
260}
261
262
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263bool StringShape::IsExternal() {
264 return (type_ & kStringRepresentationMask) == kExternalStringTag;
265}
266
267
268bool StringShape::IsSequential() {
269 return (type_ & kStringRepresentationMask) == kSeqStringTag;
270}
271
272
273StringRepresentationTag StringShape::representation_tag() {
274 uint32_t tag = (type_ & kStringRepresentationMask);
275 return static_cast<StringRepresentationTag>(tag);
276}
277
278
279uint32_t StringShape::full_representation_tag() {
280 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
281}
282
283
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000284STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
285 Internals::kFullStringRepresentationMask);
286
287
ager@chromium.org870a0b62008-11-04 11:43:05 +0000288bool StringShape::IsSequentialAscii() {
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
290}
291
292
293bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
298bool StringShape::IsExternalAscii() {
299 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305}
306
307
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000308STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
309 Internals::kExternalTwoByteRepresentationTag);
310
311
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312uc32 FlatStringReader::Get(int index) {
313 ASSERT(0 <= index && index <= length_);
314 if (is_ascii_) {
315 return static_cast<const byte*>(start_)[index];
316 } else {
317 return static_cast<const uc16*>(start_)[index];
318 }
319}
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322bool Object::IsNumber() {
323 return IsSmi() || IsHeapNumber();
324}
325
326
327bool Object::IsByteArray() {
328 return Object::IsHeapObject()
329 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
330}
331
332
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000333bool Object::IsPixelArray() {
334 return Object::IsHeapObject() &&
335 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
336}
337
338
ager@chromium.org3811b432009-10-28 14:53:37 +0000339bool Object::IsExternalArray() {
340 if (!Object::IsHeapObject())
341 return false;
342 InstanceType instance_type =
343 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000344 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
345 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000346}
347
348
349bool Object::IsExternalByteArray() {
350 return Object::IsHeapObject() &&
351 HeapObject::cast(this)->map()->instance_type() ==
352 EXTERNAL_BYTE_ARRAY_TYPE;
353}
354
355
356bool Object::IsExternalUnsignedByteArray() {
357 return Object::IsHeapObject() &&
358 HeapObject::cast(this)->map()->instance_type() ==
359 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
360}
361
362
363bool Object::IsExternalShortArray() {
364 return Object::IsHeapObject() &&
365 HeapObject::cast(this)->map()->instance_type() ==
366 EXTERNAL_SHORT_ARRAY_TYPE;
367}
368
369
370bool Object::IsExternalUnsignedShortArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalIntArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_INT_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalUnsignedIntArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalFloatArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_FLOAT_ARRAY_TYPE;
395}
396
397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398bool Object::IsFailure() {
399 return HAS_FAILURE_TAG(this);
400}
401
402
403bool Object::IsRetryAfterGC() {
404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
ager@chromium.org7c537e22008-10-16 08:43:32 +0000409bool Object::IsOutOfMemoryFailure() {
410 return HAS_FAILURE_TAG(this)
411 && Failure::cast(this)->IsOutOfMemoryException();
412}
413
414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415bool Object::IsException() {
416 return this == Failure::Exception();
417}
418
419
420bool Object::IsJSObject() {
421 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000422 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423}
424
425
ager@chromium.org32912102009-01-16 10:38:43 +0000426bool Object::IsJSContextExtensionObject() {
427 return IsHeapObject()
428 && (HeapObject::cast(this)->map()->instance_type() ==
429 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
430}
431
432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433bool Object::IsMap() {
434 return Object::IsHeapObject()
435 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
436}
437
438
439bool Object::IsFixedArray() {
440 return Object::IsHeapObject()
441 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
442}
443
444
445bool Object::IsDescriptorArray() {
446 return IsFixedArray();
447}
448
449
450bool Object::IsContext() {
451 return Object::IsHeapObject()
452 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000453 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 HeapObject::cast(this)->map() == Heap::global_context_map());
455}
456
457
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000458bool Object::IsCatchContext() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::catch_context_map();
461}
462
463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464bool Object::IsGlobalContext() {
465 return Object::IsHeapObject()
466 && HeapObject::cast(this)->map() == Heap::global_context_map();
467}
468
469
470bool Object::IsJSFunction() {
471 return Object::IsHeapObject()
472 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
473}
474
475
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000476template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 return obj->IsJSFunction();
478}
479
480
481bool Object::IsCode() {
482 return Object::IsHeapObject()
483 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
484}
485
486
487bool Object::IsOddball() {
488 return Object::IsHeapObject()
489 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
490}
491
492
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000493bool Object::IsJSGlobalPropertyCell() {
494 return Object::IsHeapObject()
495 && HeapObject::cast(this)->map()->instance_type()
496 == JS_GLOBAL_PROPERTY_CELL_TYPE;
497}
498
499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500bool Object::IsSharedFunctionInfo() {
501 return Object::IsHeapObject() &&
502 (HeapObject::cast(this)->map()->instance_type() ==
503 SHARED_FUNCTION_INFO_TYPE);
504}
505
506
507bool Object::IsJSValue() {
508 return Object::IsHeapObject()
509 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
510}
511
512
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000513bool Object::IsStringWrapper() {
514 return IsJSValue() && JSValue::cast(this)->value()->IsString();
515}
516
517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518bool Object::IsProxy() {
519 return Object::IsHeapObject()
520 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
521}
522
523
524bool Object::IsBoolean() {
525 return IsTrue() || IsFalse();
526}
527
528
529bool Object::IsJSArray() {
530 return Object::IsHeapObject()
531 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
532}
533
534
ager@chromium.org236ad962008-09-25 09:45:57 +0000535bool Object::IsJSRegExp() {
536 return Object::IsHeapObject()
537 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
538}
539
540
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000541template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 return obj->IsJSArray();
543}
544
545
546bool Object::IsHashTable() {
547 return Object::IsHeapObject()
548 && HeapObject::cast(this)->map() == Heap::hash_table_map();
549}
550
551
552bool Object::IsDictionary() {
553 return IsHashTable() && this != Heap::symbol_table();
554}
555
556
557bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000558 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
ager@chromium.orgac091b72010-05-05 07:34:42 +0000562bool Object::IsJSFunctionResultCache() {
563 if (!IsFixedArray()) return false;
564 FixedArray* self = FixedArray::cast(this);
565 int length = self->length();
566 if (length < JSFunctionResultCache::kEntriesIndex) return false;
567 if ((length - JSFunctionResultCache::kEntriesIndex)
568 % JSFunctionResultCache::kEntrySize != 0) {
569 return false;
570 }
571#ifdef DEBUG
572 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
573#endif
574 return true;
575}
576
577
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000578bool Object::IsCompilationCacheTable() {
579 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000580}
581
582
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000583bool Object::IsCodeCacheHashTable() {
584 return IsHashTable();
585}
586
587
ager@chromium.org236ad962008-09-25 09:45:57 +0000588bool Object::IsMapCache() {
589 return IsHashTable();
590}
591
592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000593bool Object::IsPrimitive() {
594 return IsOddball() || IsNumber() || IsString();
595}
596
597
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000598bool Object::IsJSGlobalProxy() {
599 bool result = IsHeapObject() &&
600 (HeapObject::cast(this)->map()->instance_type() ==
601 JS_GLOBAL_PROXY_TYPE);
602 ASSERT(!result || IsAccessCheckNeeded());
603 return result;
604}
605
606
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000608 if (!IsHeapObject()) return false;
609
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000610 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000611 return type == JS_GLOBAL_OBJECT_TYPE ||
612 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613}
614
615
616bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617 return IsHeapObject() &&
618 (HeapObject::cast(this)->map()->instance_type() ==
619 JS_GLOBAL_OBJECT_TYPE);
620}
621
622
623bool Object::IsJSBuiltinsObject() {
624 return IsHeapObject() &&
625 (HeapObject::cast(this)->map()->instance_type() ==
626 JS_BUILTINS_OBJECT_TYPE);
627}
628
629
630bool Object::IsUndetectableObject() {
631 return IsHeapObject()
632 && HeapObject::cast(this)->map()->is_undetectable();
633}
634
635
636bool Object::IsAccessCheckNeeded() {
637 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000638 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000639}
640
641
642bool Object::IsStruct() {
643 if (!IsHeapObject()) return false;
644 switch (HeapObject::cast(this)->map()->instance_type()) {
645#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
646 STRUCT_LIST(MAKE_STRUCT_CASE)
647#undef MAKE_STRUCT_CASE
648 default: return false;
649 }
650}
651
652
653#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
654 bool Object::Is##Name() { \
655 return Object::IsHeapObject() \
656 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
657 }
658 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
659#undef MAKE_STRUCT_PREDICATE
660
661
662bool Object::IsUndefined() {
663 return this == Heap::undefined_value();
664}
665
666
667bool Object::IsTheHole() {
668 return this == Heap::the_hole_value();
669}
670
671
672bool Object::IsNull() {
673 return this == Heap::null_value();
674}
675
676
677bool Object::IsTrue() {
678 return this == Heap::true_value();
679}
680
681
682bool Object::IsFalse() {
683 return this == Heap::false_value();
684}
685
686
687double Object::Number() {
688 ASSERT(IsNumber());
689 return IsSmi()
690 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
691 : reinterpret_cast<HeapNumber*>(this)->value();
692}
693
694
695
696Object* Object::ToSmi() {
697 if (IsSmi()) return this;
698 if (IsHeapNumber()) {
699 double value = HeapNumber::cast(this)->value();
700 int int_value = FastD2I(value);
701 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
702 return Smi::FromInt(int_value);
703 }
704 }
705 return Failure::Exception();
706}
707
708
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000709bool Object::HasSpecificClassOf(String* name) {
710 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
711}
712
713
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000714Object* Object::GetElement(uint32_t index) {
715 return GetElementWithReceiver(this, index);
716}
717
718
719Object* Object::GetProperty(String* key) {
720 PropertyAttributes attributes;
721 return GetPropertyWithReceiver(this, key, &attributes);
722}
723
724
725Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
726 return GetPropertyWithReceiver(this, key, attributes);
727}
728
729
730#define FIELD_ADDR(p, offset) \
731 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
732
733#define READ_FIELD(p, offset) \
734 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
735
736#define WRITE_FIELD(p, offset, value) \
737 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
738
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000739
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000740#define WRITE_BARRIER(object, offset) \
741 Heap::RecordWrite(object->address(), offset);
742
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000743// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000744// write due to the assert validating the written value.
745#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
746 if (mode == UPDATE_WRITE_BARRIER) { \
747 Heap::RecordWrite(object->address(), offset); \
748 } else { \
749 ASSERT(mode == SKIP_WRITE_BARRIER); \
750 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000751 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000752 Page::FromAddress(object->address())-> \
753 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000754 }
755
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000756#define READ_DOUBLE_FIELD(p, offset) \
757 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
758
759#define WRITE_DOUBLE_FIELD(p, offset, value) \
760 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
761
762#define READ_INT_FIELD(p, offset) \
763 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
764
765#define WRITE_INT_FIELD(p, offset, value) \
766 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
767
ager@chromium.org3e875802009-06-29 08:26:34 +0000768#define READ_INTPTR_FIELD(p, offset) \
769 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
770
771#define WRITE_INTPTR_FIELD(p, offset, value) \
772 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
773
ager@chromium.org7c537e22008-10-16 08:43:32 +0000774#define READ_UINT32_FIELD(p, offset) \
775 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
776
777#define WRITE_UINT32_FIELD(p, offset, value) \
778 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000780#define READ_SHORT_FIELD(p, offset) \
781 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
782
783#define WRITE_SHORT_FIELD(p, offset, value) \
784 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
785
786#define READ_BYTE_FIELD(p, offset) \
787 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
788
789#define WRITE_BYTE_FIELD(p, offset, value) \
790 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
791
792
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000793Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
794 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795}
796
797
798int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000799 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800}
801
802
803Smi* Smi::FromInt(int value) {
804 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000805 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000806 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000807 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000808 return reinterpret_cast<Smi*>(tagged_value);
809}
810
811
812Smi* Smi::FromIntptr(intptr_t value) {
813 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000814 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
815 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816}
817
818
819Failure::Type Failure::type() const {
820 return static_cast<Type>(value() & kFailureTypeTagMask);
821}
822
823
824bool Failure::IsInternalError() const {
825 return type() == INTERNAL_ERROR;
826}
827
828
829bool Failure::IsOutOfMemoryException() const {
830 return type() == OUT_OF_MEMORY_EXCEPTION;
831}
832
833
834int Failure::requested() const {
835 const int kShiftBits =
836 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
837 STATIC_ASSERT(kShiftBits >= 0);
838 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000839 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840}
841
842
843AllocationSpace Failure::allocation_space() const {
844 ASSERT_EQ(RETRY_AFTER_GC, type());
845 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
846 & kSpaceTagMask);
847}
848
849
850Failure* Failure::InternalError() {
851 return Construct(INTERNAL_ERROR);
852}
853
854
855Failure* Failure::Exception() {
856 return Construct(EXCEPTION);
857}
858
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860Failure* Failure::OutOfMemoryException() {
861 return Construct(OUT_OF_MEMORY_EXCEPTION);
862}
863
864
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000865intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000866 return static_cast<intptr_t>(
867 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868}
869
870
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000871Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000872 // Assert that the space encoding fits in the three bytes allotted for it.
873 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000874 uintptr_t requested =
875 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
876 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000877 if (((requested << tag_bits) >> tag_bits) != requested) {
878 // No room for entire requested size in the bits. Round down to
879 // maximally representable size.
880 requested = static_cast<intptr_t>(
881 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
882 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000883 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000884 return Construct(RETRY_AFTER_GC, value);
885}
886
887
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000888Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000889 uintptr_t info =
890 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000891 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000892 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000893}
894
895
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000896bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897#ifdef DEBUG
898 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
899#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000900
901#ifdef V8_TARGET_ARCH_X64
902 // To be representable as a long smi, the value must be a 32-bit integer.
903 bool result = (value == static_cast<int32_t>(value));
904#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905 // To be representable as an tagged small integer, the two
906 // most-significant bits of 'value' must be either 00 or 11 due to
907 // sign-extension. To check this we add 01 to the two
908 // most-significant bits, and check if the most-significant bit is 0
909 //
910 // CAUTION: The original code below:
911 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
912 // may lead to incorrect results according to the C language spec, and
913 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
914 // compiler may produce undefined results in case of signed integer
915 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000916 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000917#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000918 ASSERT(result == in_range);
919 return result;
920}
921
922
kasper.lund7276f142008-07-30 08:49:36 +0000923MapWord MapWord::FromMap(Map* map) {
924 return MapWord(reinterpret_cast<uintptr_t>(map));
925}
926
927
928Map* MapWord::ToMap() {
929 return reinterpret_cast<Map*>(value_);
930}
931
932
933bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000934 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000935}
936
937
938MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000939 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
940 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000941}
942
943
944HeapObject* MapWord::ToForwardingAddress() {
945 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000946 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000947}
948
949
950bool MapWord::IsMarked() {
951 return (value_ & kMarkingMask) == 0;
952}
953
954
955void MapWord::SetMark() {
956 value_ &= ~kMarkingMask;
957}
958
959
960void MapWord::ClearMark() {
961 value_ |= kMarkingMask;
962}
963
964
965bool MapWord::IsOverflowed() {
966 return (value_ & kOverflowMask) != 0;
967}
968
969
970void MapWord::SetOverflow() {
971 value_ |= kOverflowMask;
972}
973
974
975void MapWord::ClearOverflow() {
976 value_ &= ~kOverflowMask;
977}
978
979
980MapWord MapWord::EncodeAddress(Address map_address, int offset) {
981 // Offset is the distance in live bytes from the first live object in the
982 // same page. The offset between two objects in the same page should not
983 // exceed the object area size of a page.
984 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
985
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000986 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000987 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
988
989 Page* map_page = Page::FromAddress(map_address);
990 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
991
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000992 uintptr_t map_page_offset =
993 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000994
995 uintptr_t encoding =
996 (compact_offset << kForwardingOffsetShift) |
997 (map_page_offset << kMapPageOffsetShift) |
998 (map_page->mc_page_index << kMapPageIndexShift);
999 return MapWord(encoding);
1000}
1001
1002
1003Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001004 int map_page_index =
1005 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001006 ASSERT_MAP_PAGE_INDEX(map_page_index);
1007
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001008 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001009 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1010 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001011
1012 return (map_space->PageAddress(map_page_index) + map_page_offset);
1013}
1014
1015
1016int MapWord::DecodeOffset() {
1017 // The offset field is represented in the kForwardingOffsetBits
1018 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001019 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1020 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1021 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001022}
1023
1024
1025MapWord MapWord::FromEncodedAddress(Address address) {
1026 return MapWord(reinterpret_cast<uintptr_t>(address));
1027}
1028
1029
1030Address MapWord::ToEncodedAddress() {
1031 return reinterpret_cast<Address>(value_);
1032}
1033
1034
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001035#ifdef DEBUG
1036void HeapObject::VerifyObjectField(int offset) {
1037 VerifyPointer(READ_FIELD(this, offset));
1038}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001039
1040void HeapObject::VerifySmiField(int offset) {
1041 ASSERT(READ_FIELD(this, offset)->IsSmi());
1042}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001043#endif
1044
1045
1046Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001047 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048}
1049
1050
1051void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001052 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053}
1054
1055
kasper.lund7276f142008-07-30 08:49:36 +00001056MapWord HeapObject::map_word() {
1057 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1058}
1059
1060
1061void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001062 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001063 // here.
1064 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1065}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066
1067
1068HeapObject* HeapObject::FromAddress(Address address) {
1069 ASSERT_TAG_ALIGNED(address);
1070 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1071}
1072
1073
1074Address HeapObject::address() {
1075 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1076}
1077
1078
1079int HeapObject::Size() {
1080 return SizeFromMap(map());
1081}
1082
1083
1084void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1085 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1086 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1087}
1088
1089
1090void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1091 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1092}
1093
1094
kasper.lund7276f142008-07-30 08:49:36 +00001095bool HeapObject::IsMarked() {
1096 return map_word().IsMarked();
1097}
1098
1099
1100void HeapObject::SetMark() {
1101 ASSERT(!IsMarked());
1102 MapWord first_word = map_word();
1103 first_word.SetMark();
1104 set_map_word(first_word);
1105}
1106
1107
1108void HeapObject::ClearMark() {
1109 ASSERT(IsMarked());
1110 MapWord first_word = map_word();
1111 first_word.ClearMark();
1112 set_map_word(first_word);
1113}
1114
1115
1116bool HeapObject::IsOverflowed() {
1117 return map_word().IsOverflowed();
1118}
1119
1120
1121void HeapObject::SetOverflow() {
1122 MapWord first_word = map_word();
1123 first_word.SetOverflow();
1124 set_map_word(first_word);
1125}
1126
1127
1128void HeapObject::ClearOverflow() {
1129 ASSERT(IsOverflowed());
1130 MapWord first_word = map_word();
1131 first_word.ClearOverflow();
1132 set_map_word(first_word);
1133}
1134
1135
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001136double HeapNumber::value() {
1137 return READ_DOUBLE_FIELD(this, kValueOffset);
1138}
1139
1140
1141void HeapNumber::set_value(double value) {
1142 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1143}
1144
1145
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001146int HeapNumber::get_exponent() {
1147 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1148 kExponentShift) - kExponentBias;
1149}
1150
1151
1152int HeapNumber::get_sign() {
1153 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1154}
1155
1156
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001157ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001158
1159
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001160HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001161 Object* array = READ_FIELD(this, kElementsOffset);
1162 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001163 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1164 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001165 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001166}
1167
1168
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001169void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001170 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001171 (value->map() == Heap::fixed_array_map() ||
1172 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001173 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001174 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1175 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001176 WRITE_FIELD(this, kElementsOffset, value);
1177 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1178}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001179
1180
1181void JSObject::initialize_properties() {
1182 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1183 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1184}
1185
1186
1187void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001188 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001189 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1190 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1191}
1192
1193
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001194Object* JSObject::ResetElements() {
1195 Object* obj = map()->GetFastElementsMap();
1196 if (obj->IsFailure()) return obj;
1197 set_map(Map::cast(obj));
1198 initialize_elements();
1199 return this;
1200}
1201
1202
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001203ACCESSORS(Oddball, to_string, String, kToStringOffset)
1204ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1205
1206
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001207Object* JSGlobalPropertyCell::value() {
1208 return READ_FIELD(this, kValueOffset);
1209}
1210
1211
1212void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1213 // The write barrier is not used for global property cells.
1214 ASSERT(!val->IsJSGlobalPropertyCell());
1215 WRITE_FIELD(this, kValueOffset, val);
1216}
1217
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001220 InstanceType type = map()->instance_type();
1221 // Check for the most common kind of JavaScript object before
1222 // falling into the generic switch. This speeds up the internal
1223 // field operations considerably on average.
1224 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1225 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001226 case JS_GLOBAL_PROXY_TYPE:
1227 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001228 case JS_GLOBAL_OBJECT_TYPE:
1229 return JSGlobalObject::kSize;
1230 case JS_BUILTINS_OBJECT_TYPE:
1231 return JSBuiltinsObject::kSize;
1232 case JS_FUNCTION_TYPE:
1233 return JSFunction::kSize;
1234 case JS_VALUE_TYPE:
1235 return JSValue::kSize;
1236 case JS_ARRAY_TYPE:
1237 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001238 case JS_REGEXP_TYPE:
1239 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001240 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001241 return JSObject::kHeaderSize;
1242 default:
1243 UNREACHABLE();
1244 return 0;
1245 }
1246}
1247
1248
1249int JSObject::GetInternalFieldCount() {
1250 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001251 // Make sure to adjust for the number of in-object properties. These
1252 // properties do contribute to the size, but are not internal fields.
1253 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1254 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255}
1256
1257
1258Object* JSObject::GetInternalField(int index) {
1259 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001260 // Internal objects do follow immediately after the header, whereas in-object
1261 // properties are at the end of the object. Therefore there is no need
1262 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1264}
1265
1266
1267void JSObject::SetInternalField(int index, Object* value) {
1268 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001269 // Internal objects do follow immediately after the header, whereas in-object
1270 // properties are at the end of the object. Therefore there is no need
1271 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001272 int offset = GetHeaderSize() + (kPointerSize * index);
1273 WRITE_FIELD(this, offset, value);
1274 WRITE_BARRIER(this, offset);
1275}
1276
1277
ager@chromium.org7c537e22008-10-16 08:43:32 +00001278// Access fast-case object properties at index. The use of these routines
1279// is needed to correctly distinguish between properties stored in-object and
1280// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001281Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001282 // Adjust for the number of properties stored in the object.
1283 index -= map()->inobject_properties();
1284 if (index < 0) {
1285 int offset = map()->instance_size() + (index * kPointerSize);
1286 return READ_FIELD(this, offset);
1287 } else {
1288 ASSERT(index < properties()->length());
1289 return properties()->get(index);
1290 }
1291}
1292
1293
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001294Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001295 // Adjust for the number of properties stored in the object.
1296 index -= map()->inobject_properties();
1297 if (index < 0) {
1298 int offset = map()->instance_size() + (index * kPointerSize);
1299 WRITE_FIELD(this, offset, value);
1300 WRITE_BARRIER(this, offset);
1301 } else {
1302 ASSERT(index < properties()->length());
1303 properties()->set(index, value);
1304 }
1305 return value;
1306}
1307
1308
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001309Object* JSObject::InObjectPropertyAt(int index) {
1310 // Adjust for the number of properties stored in the object.
1311 index -= map()->inobject_properties();
1312 ASSERT(index < 0);
1313 int offset = map()->instance_size() + (index * kPointerSize);
1314 return READ_FIELD(this, offset);
1315}
1316
1317
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001318Object* JSObject::InObjectPropertyAtPut(int index,
1319 Object* value,
1320 WriteBarrierMode mode) {
1321 // Adjust for the number of properties stored in the object.
1322 index -= map()->inobject_properties();
1323 ASSERT(index < 0);
1324 int offset = map()->instance_size() + (index * kPointerSize);
1325 WRITE_FIELD(this, offset, value);
1326 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1327 return value;
1328}
1329
1330
1331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001332void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001333 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001335 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001336 }
1337}
1338
1339
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001340bool JSObject::HasFastProperties() {
1341 return !properties()->IsDictionary();
1342}
1343
1344
1345int JSObject::MaxFastProperties() {
1346 // Allow extra fast properties if the object has more than
1347 // kMaxFastProperties in-object properties. When this is the case,
1348 // it is very unlikely that the object is being used as a dictionary
1349 // and there is a good chance that allowing more map transitions
1350 // will be worth it.
1351 return Max(map()->inobject_properties(), kMaxFastProperties);
1352}
1353
1354
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001355void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001356 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001357 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001358 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359 }
1360}
1361
1362
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001363bool Object::ToArrayIndex(uint32_t* index) {
1364 if (IsSmi()) {
1365 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001366 if (value < 0) return false;
1367 *index = value;
1368 return true;
1369 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001370 if (IsHeapNumber()) {
1371 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372 uint32_t uint_value = static_cast<uint32_t>(value);
1373 if (value == static_cast<double>(uint_value)) {
1374 *index = uint_value;
1375 return true;
1376 }
1377 }
1378 return false;
1379}
1380
1381
1382bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1383 if (!this->IsJSValue()) return false;
1384
1385 JSValue* js_value = JSValue::cast(this);
1386 if (!js_value->value()->IsString()) return false;
1387
1388 String* str = String::cast(js_value->value());
1389 if (index >= (uint32_t)str->length()) return false;
1390
1391 return true;
1392}
1393
1394
1395Object* FixedArray::get(int index) {
1396 ASSERT(index >= 0 && index < this->length());
1397 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1398}
1399
1400
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001401void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001402 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001403 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1404 int offset = kHeaderSize + index * kPointerSize;
1405 WRITE_FIELD(this, offset, value);
1406}
1407
1408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001410 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411 ASSERT(index >= 0 && index < this->length());
1412 int offset = kHeaderSize + index * kPointerSize;
1413 WRITE_FIELD(this, offset, value);
1414 WRITE_BARRIER(this, offset);
1415}
1416
1417
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001418WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1420 return UPDATE_WRITE_BARRIER;
1421}
1422
1423
1424void FixedArray::set(int index,
1425 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001426 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001427 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001428 ASSERT(index >= 0 && index < this->length());
1429 int offset = kHeaderSize + index * kPointerSize;
1430 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001431 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432}
1433
1434
1435void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001436 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001437 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001438 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1440}
1441
1442
1443void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001444 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445 ASSERT(index >= 0 && index < this->length());
1446 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1447 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1448 Heap::undefined_value());
1449}
1450
1451
ager@chromium.org236ad962008-09-25 09:45:57 +00001452void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001453 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001454 ASSERT(index >= 0 && index < this->length());
1455 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1456 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1457}
1458
1459
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001461 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001462 ASSERT(index >= 0 && index < this->length());
1463 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1464 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1465}
1466
1467
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001468void FixedArray::set_unchecked(int index, Smi* value) {
1469 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1470 int offset = kHeaderSize + index * kPointerSize;
1471 WRITE_FIELD(this, offset, value);
1472}
1473
1474
1475void FixedArray::set_null_unchecked(int index) {
1476 ASSERT(index >= 0 && index < this->length());
1477 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1478 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1479}
1480
1481
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001482Object** FixedArray::data_start() {
1483 return HeapObject::RawField(this, kHeaderSize);
1484}
1485
1486
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001487bool DescriptorArray::IsEmpty() {
1488 ASSERT(this == Heap::empty_descriptor_array() ||
1489 this->length() > 2);
1490 return this == Heap::empty_descriptor_array();
1491}
1492
1493
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1495 Object* tmp = array->get(first);
1496 fast_set(array, first, array->get(second));
1497 fast_set(array, second, tmp);
1498}
1499
1500
1501int DescriptorArray::Search(String* name) {
1502 SLOW_ASSERT(IsSortedNoDuplicates());
1503
1504 // Check for empty descriptor array.
1505 int nof = number_of_descriptors();
1506 if (nof == 0) return kNotFound;
1507
1508 // Fast case: do linear search for small arrays.
1509 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001510 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001511 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001512 }
1513
1514 // Slow case: perform binary search.
1515 return BinarySearch(name, 0, nof - 1);
1516}
1517
1518
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001519int DescriptorArray::SearchWithCache(String* name) {
1520 int number = DescriptorLookupCache::Lookup(this, name);
1521 if (number == DescriptorLookupCache::kAbsent) {
1522 number = Search(name);
1523 DescriptorLookupCache::Update(this, name, number);
1524 }
1525 return number;
1526}
1527
1528
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529String* DescriptorArray::GetKey(int descriptor_number) {
1530 ASSERT(descriptor_number < number_of_descriptors());
1531 return String::cast(get(ToKeyIndex(descriptor_number)));
1532}
1533
1534
1535Object* DescriptorArray::GetValue(int descriptor_number) {
1536 ASSERT(descriptor_number < number_of_descriptors());
1537 return GetContentArray()->get(ToValueIndex(descriptor_number));
1538}
1539
1540
1541Smi* DescriptorArray::GetDetails(int descriptor_number) {
1542 ASSERT(descriptor_number < number_of_descriptors());
1543 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1544}
1545
1546
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001547PropertyType DescriptorArray::GetType(int descriptor_number) {
1548 ASSERT(descriptor_number < number_of_descriptors());
1549 return PropertyDetails(GetDetails(descriptor_number)).type();
1550}
1551
1552
1553int DescriptorArray::GetFieldIndex(int descriptor_number) {
1554 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1555}
1556
1557
1558JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1559 return JSFunction::cast(GetValue(descriptor_number));
1560}
1561
1562
1563Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1564 ASSERT(GetType(descriptor_number) == CALLBACKS);
1565 return GetValue(descriptor_number);
1566}
1567
1568
1569AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1570 ASSERT(GetType(descriptor_number) == CALLBACKS);
1571 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1572 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1573}
1574
1575
1576bool DescriptorArray::IsProperty(int descriptor_number) {
1577 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1578}
1579
1580
1581bool DescriptorArray::IsTransition(int descriptor_number) {
1582 PropertyType t = GetType(descriptor_number);
1583 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1584}
1585
1586
1587bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1588 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1589}
1590
1591
1592bool DescriptorArray::IsDontEnum(int descriptor_number) {
1593 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1594}
1595
1596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001597void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1598 desc->Init(GetKey(descriptor_number),
1599 GetValue(descriptor_number),
1600 GetDetails(descriptor_number));
1601}
1602
1603
1604void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1605 // Range check.
1606 ASSERT(descriptor_number < number_of_descriptors());
1607
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001608 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1610 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1611
1612 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1613 FixedArray* content_array = GetContentArray();
1614 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1615 fast_set(content_array, ToDetailsIndex(descriptor_number),
1616 desc->GetDetails().AsSmi());
1617}
1618
1619
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001620void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1621 Descriptor desc;
1622 src->Get(src_index, &desc);
1623 Set(index, &desc);
1624}
1625
1626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001627void DescriptorArray::Swap(int first, int second) {
1628 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1629 FixedArray* content_array = GetContentArray();
1630 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1631 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1632}
1633
1634
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001635bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001636 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 if (!max_index_object->IsSmi()) return false;
1638 return 0 !=
1639 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1640}
1641
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001642uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001643 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001644 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645 if (!max_index_object->IsSmi()) return 0;
1646 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1647 return value >> kRequiresSlowElementsTagSize;
1648}
1649
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001650void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001651 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001652}
1653
1654
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655// ------------------------------------
1656// Cast operations
1657
1658
1659CAST_ACCESSOR(FixedArray)
1660CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001661CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001662CAST_ACCESSOR(JSFunctionResultCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001663CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001664CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001665CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666CAST_ACCESSOR(String)
1667CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001668CAST_ACCESSOR(SeqAsciiString)
1669CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671CAST_ACCESSOR(ExternalString)
1672CAST_ACCESSOR(ExternalAsciiString)
1673CAST_ACCESSOR(ExternalTwoByteString)
1674CAST_ACCESSOR(JSObject)
1675CAST_ACCESSOR(Smi)
1676CAST_ACCESSOR(Failure)
1677CAST_ACCESSOR(HeapObject)
1678CAST_ACCESSOR(HeapNumber)
1679CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001680CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681CAST_ACCESSOR(SharedFunctionInfo)
1682CAST_ACCESSOR(Map)
1683CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001684CAST_ACCESSOR(GlobalObject)
1685CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001686CAST_ACCESSOR(JSGlobalObject)
1687CAST_ACCESSOR(JSBuiltinsObject)
1688CAST_ACCESSOR(Code)
1689CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001690CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691CAST_ACCESSOR(Proxy)
1692CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001693CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001694CAST_ACCESSOR(ExternalArray)
1695CAST_ACCESSOR(ExternalByteArray)
1696CAST_ACCESSOR(ExternalUnsignedByteArray)
1697CAST_ACCESSOR(ExternalShortArray)
1698CAST_ACCESSOR(ExternalUnsignedShortArray)
1699CAST_ACCESSOR(ExternalIntArray)
1700CAST_ACCESSOR(ExternalUnsignedIntArray)
1701CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702CAST_ACCESSOR(Struct)
1703
1704
1705#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1706 STRUCT_LIST(MAKE_STRUCT_CAST)
1707#undef MAKE_STRUCT_CAST
1708
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001709
1710template <typename Shape, typename Key>
1711HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712 ASSERT(obj->IsHashTable());
1713 return reinterpret_cast<HashTable*>(obj);
1714}
1715
1716
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001717SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1718SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1719
1720INT_ACCESSORS(PixelArray, length, kLengthOffset)
1721INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722
1723
ager@chromium.orgac091b72010-05-05 07:34:42 +00001724SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001725
1726
1727uint32_t String::hash_field() {
1728 return READ_UINT32_FIELD(this, kHashFieldOffset);
1729}
1730
1731
1732void String::set_hash_field(uint32_t value) {
1733 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001734#if V8_HOST_ARCH_64_BIT
1735 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1736#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001737}
1738
1739
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001740bool String::Equals(String* other) {
1741 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001742 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1743 return false;
1744 }
1745 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001746}
1747
1748
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001749Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001750 if (!StringShape(this).IsCons()) return this;
1751 ConsString* cons = ConsString::cast(this);
1752 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001753 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754}
1755
1756
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001757String* String::TryFlattenGetString(PretenureFlag pretenure) {
1758 Object* flat = TryFlatten(pretenure);
1759 return flat->IsFailure() ? this : String::cast(flat);
1760}
1761
1762
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001763uint16_t String::Get(int index) {
1764 ASSERT(index >= 0 && index < length());
1765 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001766 case kSeqStringTag | kAsciiStringTag:
1767 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1768 case kSeqStringTag | kTwoByteStringTag:
1769 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1770 case kConsStringTag | kAsciiStringTag:
1771 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001773 case kExternalStringTag | kAsciiStringTag:
1774 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1775 case kExternalStringTag | kTwoByteStringTag:
1776 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001777 default:
1778 break;
1779 }
1780
1781 UNREACHABLE();
1782 return 0;
1783}
1784
1785
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001786void String::Set(int index, uint16_t value) {
1787 ASSERT(index >= 0 && index < length());
1788 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001789
ager@chromium.org5ec48922009-05-05 07:25:34 +00001790 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001791 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1792 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793}
1794
1795
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001796bool String::IsFlat() {
1797 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001798 case kConsStringTag: {
1799 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001800 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001801 return second->length() == 0;
1802 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001803 default:
1804 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 }
1806}
1807
1808
ager@chromium.org7c537e22008-10-16 08:43:32 +00001809uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 ASSERT(index >= 0 && index < length());
1811 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1812}
1813
1814
ager@chromium.org7c537e22008-10-16 08:43:32 +00001815void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1817 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1818 static_cast<byte>(value));
1819}
1820
1821
ager@chromium.org7c537e22008-10-16 08:43:32 +00001822Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 return FIELD_ADDR(this, kHeaderSize);
1824}
1825
1826
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001827char* SeqAsciiString::GetChars() {
1828 return reinterpret_cast<char*>(GetCharsAddress());
1829}
1830
1831
ager@chromium.org7c537e22008-10-16 08:43:32 +00001832Address SeqTwoByteString::GetCharsAddress() {
1833 return FIELD_ADDR(this, kHeaderSize);
1834}
1835
1836
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001837uc16* SeqTwoByteString::GetChars() {
1838 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1839}
1840
1841
ager@chromium.org7c537e22008-10-16 08:43:32 +00001842uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001843 ASSERT(index >= 0 && index < length());
1844 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1845}
1846
1847
ager@chromium.org7c537e22008-10-16 08:43:32 +00001848void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 ASSERT(index >= 0 && index < length());
1850 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1851}
1852
1853
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001854int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001855 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856}
1857
1858
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001859int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001860 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861}
1862
1863
ager@chromium.org870a0b62008-11-04 11:43:05 +00001864String* ConsString::first() {
1865 return String::cast(READ_FIELD(this, kFirstOffset));
1866}
1867
1868
1869Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870 return READ_FIELD(this, kFirstOffset);
1871}
1872
1873
ager@chromium.org870a0b62008-11-04 11:43:05 +00001874void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001876 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877}
1878
1879
ager@chromium.org870a0b62008-11-04 11:43:05 +00001880String* ConsString::second() {
1881 return String::cast(READ_FIELD(this, kSecondOffset));
1882}
1883
1884
1885Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001886 return READ_FIELD(this, kSecondOffset);
1887}
1888
1889
ager@chromium.org870a0b62008-11-04 11:43:05 +00001890void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001892 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893}
1894
1895
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001896ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1897 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1898}
1899
1900
1901void ExternalAsciiString::set_resource(
1902 ExternalAsciiString::Resource* resource) {
1903 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1904}
1905
1906
1907ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1908 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1909}
1910
1911
1912void ExternalTwoByteString::set_resource(
1913 ExternalTwoByteString::Resource* resource) {
1914 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1915}
1916
1917
ager@chromium.orgac091b72010-05-05 07:34:42 +00001918void JSFunctionResultCache::MakeZeroSize() {
1919 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1920 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1921}
1922
1923
1924void JSFunctionResultCache::Clear() {
1925 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1926 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1927 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1928 MakeZeroSize();
1929}
1930
1931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932byte ByteArray::get(int index) {
1933 ASSERT(index >= 0 && index < this->length());
1934 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1935}
1936
1937
1938void ByteArray::set(int index, byte value) {
1939 ASSERT(index >= 0 && index < this->length());
1940 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1941}
1942
1943
1944int ByteArray::get_int(int index) {
1945 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1946 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1947}
1948
1949
1950ByteArray* ByteArray::FromDataStartAddress(Address address) {
1951 ASSERT_TAG_ALIGNED(address);
1952 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1953}
1954
1955
1956Address ByteArray::GetDataStartAddress() {
1957 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1958}
1959
1960
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001961uint8_t* PixelArray::external_pointer() {
1962 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1963 return reinterpret_cast<uint8_t*>(ptr);
1964}
1965
1966
1967void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1968 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1969 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1970}
1971
1972
1973uint8_t PixelArray::get(int index) {
1974 ASSERT((index >= 0) && (index < this->length()));
1975 uint8_t* ptr = external_pointer();
1976 return ptr[index];
1977}
1978
1979
1980void PixelArray::set(int index, uint8_t value) {
1981 ASSERT((index >= 0) && (index < this->length()));
1982 uint8_t* ptr = external_pointer();
1983 ptr[index] = value;
1984}
1985
1986
ager@chromium.org3811b432009-10-28 14:53:37 +00001987void* ExternalArray::external_pointer() {
1988 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1989 return reinterpret_cast<void*>(ptr);
1990}
1991
1992
1993void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1994 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1995 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1996}
1997
1998
1999int8_t ExternalByteArray::get(int index) {
2000 ASSERT((index >= 0) && (index < this->length()));
2001 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2002 return ptr[index];
2003}
2004
2005
2006void ExternalByteArray::set(int index, int8_t value) {
2007 ASSERT((index >= 0) && (index < this->length()));
2008 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2009 ptr[index] = value;
2010}
2011
2012
2013uint8_t ExternalUnsignedByteArray::get(int index) {
2014 ASSERT((index >= 0) && (index < this->length()));
2015 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2016 return ptr[index];
2017}
2018
2019
2020void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2021 ASSERT((index >= 0) && (index < this->length()));
2022 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2023 ptr[index] = value;
2024}
2025
2026
2027int16_t ExternalShortArray::get(int index) {
2028 ASSERT((index >= 0) && (index < this->length()));
2029 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2030 return ptr[index];
2031}
2032
2033
2034void ExternalShortArray::set(int index, int16_t value) {
2035 ASSERT((index >= 0) && (index < this->length()));
2036 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2037 ptr[index] = value;
2038}
2039
2040
2041uint16_t ExternalUnsignedShortArray::get(int index) {
2042 ASSERT((index >= 0) && (index < this->length()));
2043 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2044 return ptr[index];
2045}
2046
2047
2048void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2049 ASSERT((index >= 0) && (index < this->length()));
2050 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2051 ptr[index] = value;
2052}
2053
2054
2055int32_t ExternalIntArray::get(int index) {
2056 ASSERT((index >= 0) && (index < this->length()));
2057 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2058 return ptr[index];
2059}
2060
2061
2062void ExternalIntArray::set(int index, int32_t value) {
2063 ASSERT((index >= 0) && (index < this->length()));
2064 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2065 ptr[index] = value;
2066}
2067
2068
2069uint32_t ExternalUnsignedIntArray::get(int index) {
2070 ASSERT((index >= 0) && (index < this->length()));
2071 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2072 return ptr[index];
2073}
2074
2075
2076void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2077 ASSERT((index >= 0) && (index < this->length()));
2078 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2079 ptr[index] = value;
2080}
2081
2082
2083float ExternalFloatArray::get(int index) {
2084 ASSERT((index >= 0) && (index < this->length()));
2085 float* ptr = static_cast<float*>(external_pointer());
2086 return ptr[index];
2087}
2088
2089
2090void ExternalFloatArray::set(int index, float value) {
2091 ASSERT((index >= 0) && (index < this->length()));
2092 float* ptr = static_cast<float*>(external_pointer());
2093 ptr[index] = value;
2094}
2095
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002096
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002097INT_ACCESSORS(Map, visitor_id, kScavengerCallbackOffset)
ager@chromium.org3811b432009-10-28 14:53:37 +00002098
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002100 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2101}
2102
2103
2104int Map::inobject_properties() {
2105 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002106}
2107
2108
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002109int Map::pre_allocated_property_fields() {
2110 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2111}
2112
2113
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002115 int instance_size = map->instance_size();
2116 if (instance_size != kVariableSizeSentinel) return instance_size;
2117 // We can ignore the "symbol" bit becase it is only set for symbols
2118 // and implies a string type.
2119 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002120 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002122 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002124 if (instance_type == ASCII_STRING_TYPE) {
2125 return SeqAsciiString::SizeFor(
2126 reinterpret_cast<SeqAsciiString*>(this)->length());
2127 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002128 if (instance_type == BYTE_ARRAY_TYPE) {
2129 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2130 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002131 if (instance_type == STRING_TYPE) {
2132 return SeqTwoByteString::SizeFor(
2133 reinterpret_cast<SeqTwoByteString*>(this)->length());
2134 }
2135 ASSERT(instance_type == CODE_TYPE);
2136 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137}
2138
2139
2140void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002141 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002142 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143 ASSERT(0 <= value && value < 256);
2144 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2145}
2146
2147
ager@chromium.org7c537e22008-10-16 08:43:32 +00002148void Map::set_inobject_properties(int value) {
2149 ASSERT(0 <= value && value < 256);
2150 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2151}
2152
2153
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002154void Map::set_pre_allocated_property_fields(int value) {
2155 ASSERT(0 <= value && value < 256);
2156 WRITE_BYTE_FIELD(this,
2157 kPreAllocatedPropertyFieldsOffset,
2158 static_cast<byte>(value));
2159}
2160
2161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002162InstanceType Map::instance_type() {
2163 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2164}
2165
2166
2167void Map::set_instance_type(InstanceType value) {
2168 ASSERT(0 <= value && value < 256);
2169 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2170}
2171
2172
2173int Map::unused_property_fields() {
2174 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2175}
2176
2177
2178void Map::set_unused_property_fields(int value) {
2179 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2180}
2181
2182
2183byte Map::bit_field() {
2184 return READ_BYTE_FIELD(this, kBitFieldOffset);
2185}
2186
2187
2188void Map::set_bit_field(byte value) {
2189 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2190}
2191
2192
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002193byte Map::bit_field2() {
2194 return READ_BYTE_FIELD(this, kBitField2Offset);
2195}
2196
2197
2198void Map::set_bit_field2(byte value) {
2199 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2200}
2201
2202
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002203void Map::set_non_instance_prototype(bool value) {
2204 if (value) {
2205 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2206 } else {
2207 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2208 }
2209}
2210
2211
2212bool Map::has_non_instance_prototype() {
2213 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2214}
2215
2216
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002217void Map::set_function_with_prototype(bool value) {
2218 if (value) {
2219 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2220 } else {
2221 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2222 }
2223}
2224
2225
2226bool Map::function_with_prototype() {
2227 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2228}
2229
2230
ager@chromium.org870a0b62008-11-04 11:43:05 +00002231void Map::set_is_access_check_needed(bool access_check_needed) {
2232 if (access_check_needed) {
2233 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2234 } else {
2235 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2236 }
2237}
2238
2239
2240bool Map::is_access_check_needed() {
2241 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2242}
2243
2244
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002245void Map::set_is_extensible(bool value) {
2246 if (value) {
2247 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2248 } else {
2249 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2250 }
2251}
2252
2253bool Map::is_extensible() {
2254 return ((1 << kIsExtensible) & bit_field2()) != 0;
2255}
2256
2257
2258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259Code::Flags Code::flags() {
2260 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2261}
2262
2263
2264void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002265 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002266 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002267 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2268 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 ExtractArgumentsCountFromFlags(flags) >= 0);
2270 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2271}
2272
2273
2274Code::Kind Code::kind() {
2275 return ExtractKindFromFlags(flags());
2276}
2277
2278
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002279InLoopFlag Code::ic_in_loop() {
2280 return ExtractICInLoopFromFlags(flags());
2281}
2282
2283
kasper.lund7276f142008-07-30 08:49:36 +00002284InlineCacheState Code::ic_state() {
2285 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 // Only allow uninitialized or debugger states for non-IC code
2287 // objects. This is used in the debugger to determine whether or not
2288 // a call to code object has been replaced with a debug break call.
2289 ASSERT(is_inline_cache_stub() ||
2290 result == UNINITIALIZED ||
2291 result == DEBUG_BREAK ||
2292 result == DEBUG_PREPARE_STEP_IN);
2293 return result;
2294}
2295
2296
2297PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002298 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299 return ExtractTypeFromFlags(flags());
2300}
2301
2302
2303int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002304 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305 return ExtractArgumentsCountFromFlags(flags());
2306}
2307
2308
2309CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002310 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002311 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2312 kStubMajorKeyOffset));
2313}
2314
2315
2316void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002317 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002318 ASSERT(0 <= major && major < 256);
2319 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
2323bool Code::is_inline_cache_stub() {
2324 Kind kind = this->kind();
2325 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2326}
2327
2328
2329Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002330 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002331 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002332 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002333 int argc,
2334 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335 // Compute the bit mask.
2336 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002337 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002338 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339 bits |= type << kFlagsTypeShift;
2340 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002341 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342 // Cast to flags and validate result before returning it.
2343 Flags result = static_cast<Flags>(bits);
2344 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002345 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002346 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347 ASSERT(ExtractTypeFromFlags(result) == type);
2348 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2349 return result;
2350}
2351
2352
2353Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2354 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002355 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002356 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002358 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359}
2360
2361
2362Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2363 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2364 return static_cast<Kind>(bits);
2365}
2366
2367
kasper.lund7276f142008-07-30 08:49:36 +00002368InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2369 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370 return static_cast<InlineCacheState>(bits);
2371}
2372
2373
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002374InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2375 int bits = (flags & kFlagsICInLoopMask);
2376 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2377}
2378
2379
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2381 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2382 return static_cast<PropertyType>(bits);
2383}
2384
2385
2386int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2387 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2388}
2389
2390
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002391InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2392 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2393 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2394}
2395
2396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2398 int bits = flags & ~kFlagsTypeMask;
2399 return static_cast<Flags>(bits);
2400}
2401
2402
ager@chromium.org8bb60582008-12-11 12:02:20 +00002403Code* Code::GetCodeFromTargetAddress(Address address) {
2404 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2405 // GetCodeFromTargetAddress might be called when marking objects during mark
2406 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2407 // Code::cast. Code::cast does not work when the object's map is
2408 // marked.
2409 Code* result = reinterpret_cast<Code*>(code);
2410 return result;
2411}
2412
2413
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002414Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2415 return HeapObject::
2416 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2417}
2418
2419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420Object* Map::prototype() {
2421 return READ_FIELD(this, kPrototypeOffset);
2422}
2423
2424
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002425void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426 ASSERT(value->IsNull() || value->IsJSObject());
2427 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002428 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002429}
2430
2431
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002432Object* Map::GetFastElementsMap() {
2433 if (has_fast_elements()) return this;
2434 Object* obj = CopyDropTransitions();
2435 if (obj->IsFailure()) return obj;
2436 Map* new_map = Map::cast(obj);
2437 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002438 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002439 return new_map;
2440}
2441
2442
2443Object* Map::GetSlowElementsMap() {
2444 if (!has_fast_elements()) return this;
2445 Object* obj = CopyDropTransitions();
2446 if (obj->IsFailure()) return obj;
2447 Map* new_map = Map::cast(obj);
2448 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002449 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002450 return new_map;
2451}
2452
2453
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002454ACCESSORS(Map, instance_descriptors, DescriptorArray,
2455 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002456ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002457ACCESSORS(Map, constructor, Object, kConstructorOffset)
2458
2459ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2460ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2461
2462ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2463ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002464ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002466ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467
2468ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2469ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2470ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2471ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2472ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002473ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474
2475ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2476ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2477ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2478
2479ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2480ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2481ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2482ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2483ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2484ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2485
2486ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2487ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2488
2489ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2490ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2491
2492ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2493ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002494ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2495 kPropertyAccessorsOffset)
2496ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2497 kPrototypeTemplateOffset)
2498ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2499ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2500 kNamedPropertyHandlerOffset)
2501ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2502 kIndexedPropertyHandlerOffset)
2503ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2504 kInstanceTemplateOffset)
2505ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2506ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2508 kInstanceCallHandlerOffset)
2509ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2510 kAccessCheckInfoOffset)
2511ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2512
2513ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002514ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2515 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516
2517ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2518ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2519
2520ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2521
2522ACCESSORS(Script, source, Object, kSourceOffset)
2523ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002524ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002525ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2526ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002527ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002528ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2530ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002531ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002532ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002533ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002534ACCESSORS(Script, eval_from_instructions_offset, Smi,
2535 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002537#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002538ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2539ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2540ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2541ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2542
2543ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2544ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2545ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2546ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002547#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002548
2549ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002550ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002551ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2552 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002553ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002554ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2555ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002556ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002557ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2558 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002559
2560BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2561 kHiddenPrototypeBit)
2562BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2563BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2564 kNeedsAccessCheckBit)
2565BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2566 kIsExpressionBit)
2567BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2568 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002569BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002570 has_only_simple_this_property_assignments,
2571 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002572BOOL_ACCESSORS(SharedFunctionInfo,
2573 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002574 try_full_codegen,
2575 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002576BOOL_ACCESSORS(SharedFunctionInfo,
2577 compiler_hints,
2578 allows_lazy_compilation,
2579 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002581
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002582#if V8_HOST_ARCH_32_BIT
2583SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2584SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002586SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002587 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002588SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2589SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002591SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2592SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002593 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002594SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002595 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002596SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002597 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002598#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002600#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2601 int holder::name() { \
2602 int value = READ_INT_FIELD(this, offset); \
2603 ASSERT(kHeapObjectTag == 1); \
2604 ASSERT((value & kHeapObjectTag) == 0); \
2605 return value >> 1; \
2606 } \
2607 void holder::set_##name(int value) { \
2608 ASSERT(kHeapObjectTag == 1); \
2609 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2610 (value & 0xC0000000) == 0x000000000); \
2611 WRITE_INT_FIELD(this, \
2612 offset, \
2613 (value << 1) & ~kHeapObjectTag); \
2614 }
2615
2616#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2617 INT_ACCESSORS(holder, name, offset)
2618
2619
2620
2621PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2622PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2623 kFormalParameterCountOffset)
2624
2625PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2626 kExpectedNofPropertiesOffset)
2627PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2628
2629PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2630 kStartPositionAndTypeOffset)
2631PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2632
2633PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2634 kFunctionTokenPositionOffset)
2635PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2636 kCompilerHintsOffset)
2637
2638PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2639 kThisPropertyAssignmentsCountOffset)
2640#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002642ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2643ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2644
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002645bool Script::HasValidSource() {
2646 Object* src = this->source();
2647 if (!src->IsString()) return true;
2648 String* src_str = String::cast(src);
2649 if (!StringShape(src_str).IsExternal()) return true;
2650 if (src_str->IsAsciiRepresentation()) {
2651 return ExternalAsciiString::cast(src)->resource() != NULL;
2652 } else if (src_str->IsTwoByteRepresentation()) {
2653 return ExternalTwoByteString::cast(src)->resource() != NULL;
2654 }
2655 return true;
2656}
2657
2658
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002659void SharedFunctionInfo::DontAdaptArguments() {
2660 ASSERT(code()->kind() == Code::BUILTIN);
2661 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2662}
2663
2664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665int SharedFunctionInfo::start_position() {
2666 return start_position_and_type() >> kStartPositionShift;
2667}
2668
2669
2670void SharedFunctionInfo::set_start_position(int start_position) {
2671 set_start_position_and_type((start_position << kStartPositionShift)
2672 | (start_position_and_type() & ~kStartPositionMask));
2673}
2674
2675
2676Code* SharedFunctionInfo::code() {
2677 return Code::cast(READ_FIELD(this, kCodeOffset));
2678}
2679
2680
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002681Code* SharedFunctionInfo::unchecked_code() {
2682 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2683}
2684
2685
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002686void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002687 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002688 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002689}
2690
2691
ager@chromium.orgb5737492010-07-15 09:29:43 +00002692SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2693 return reinterpret_cast<SerializedScopeInfo*>(
2694 READ_FIELD(this, kScopeInfoOffset));
2695}
2696
2697
2698void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2699 WriteBarrierMode mode) {
2700 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2701 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2702}
2703
2704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002705bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002706 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002707}
2708
2709
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002710bool SharedFunctionInfo::IsApiFunction() {
2711 return function_data()->IsFunctionTemplateInfo();
2712}
2713
2714
2715FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2716 ASSERT(IsApiFunction());
2717 return FunctionTemplateInfo::cast(function_data());
2718}
2719
2720
2721bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002722 return function_data()->IsSmi();
2723}
2724
2725
2726int SharedFunctionInfo::custom_call_generator_id() {
2727 ASSERT(HasCustomCallGenerator());
2728 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002729}
2730
2731
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002732int SharedFunctionInfo::code_age() {
2733 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2734}
2735
2736
2737void SharedFunctionInfo::set_code_age(int code_age) {
2738 set_compiler_hints(compiler_hints() |
2739 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2740}
2741
2742
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002743bool JSFunction::IsBuiltin() {
2744 return context()->global()->IsJSBuiltinsObject();
2745}
2746
2747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002748Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002749 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750}
2751
2752
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002753Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002754 return reinterpret_cast<Code*>(
2755 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002756}
2757
2758
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002759void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002760 // Skip the write barrier because code is never in new space.
2761 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002762 Address entry = value->entry();
2763 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764}
2765
2766
2767Context* JSFunction::context() {
2768 return Context::cast(READ_FIELD(this, kContextOffset));
2769}
2770
2771
2772Object* JSFunction::unchecked_context() {
2773 return READ_FIELD(this, kContextOffset);
2774}
2775
2776
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002777SharedFunctionInfo* JSFunction::unchecked_shared() {
2778 return reinterpret_cast<SharedFunctionInfo*>(
2779 READ_FIELD(this, kSharedFunctionInfoOffset));
2780}
2781
2782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783void JSFunction::set_context(Object* value) {
2784 ASSERT(value == Heap::undefined_value() || value->IsContext());
2785 WRITE_FIELD(this, kContextOffset, value);
2786 WRITE_BARRIER(this, kContextOffset);
2787}
2788
2789ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2790 kPrototypeOrInitialMapOffset)
2791
2792
2793Map* JSFunction::initial_map() {
2794 return Map::cast(prototype_or_initial_map());
2795}
2796
2797
2798void JSFunction::set_initial_map(Map* value) {
2799 set_prototype_or_initial_map(value);
2800}
2801
2802
2803bool JSFunction::has_initial_map() {
2804 return prototype_or_initial_map()->IsMap();
2805}
2806
2807
2808bool JSFunction::has_instance_prototype() {
2809 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2810}
2811
2812
2813bool JSFunction::has_prototype() {
2814 return map()->has_non_instance_prototype() || has_instance_prototype();
2815}
2816
2817
2818Object* JSFunction::instance_prototype() {
2819 ASSERT(has_instance_prototype());
2820 if (has_initial_map()) return initial_map()->prototype();
2821 // When there is no initial map and the prototype is a JSObject, the
2822 // initial map field is used for the prototype field.
2823 return prototype_or_initial_map();
2824}
2825
2826
2827Object* JSFunction::prototype() {
2828 ASSERT(has_prototype());
2829 // If the function's prototype property has been set to a non-JSObject
2830 // value, that value is stored in the constructor field of the map.
2831 if (map()->has_non_instance_prototype()) return map()->constructor();
2832 return instance_prototype();
2833}
2834
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002835bool JSFunction::should_have_prototype() {
2836 return map()->function_with_prototype();
2837}
2838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002839
2840bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002841 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842}
2843
2844
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002845int JSFunction::NumberOfLiterals() {
2846 return literals()->length();
2847}
2848
2849
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002850Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2851 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002852 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002853}
2854
2855
2856void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2857 Object* value) {
2858 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002859 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2860 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2861}
2862
2863
2864Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2865 ASSERT(0 <= id && id < kJSBuiltinsCount);
2866 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2867}
2868
2869
2870void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2871 Code* value) {
2872 ASSERT(0 <= id && id < kJSBuiltinsCount);
2873 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2874 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002875}
2876
2877
2878Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002879 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002880}
2881
2882
2883void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002884 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885}
2886
2887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002888ACCESSORS(JSValue, value, Object, kValueOffset)
2889
2890
2891JSValue* JSValue::cast(Object* obj) {
2892 ASSERT(obj->IsJSValue());
2893 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2894 return reinterpret_cast<JSValue*>(obj);
2895}
2896
2897
2898INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002899ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002900
2901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902byte* Code::instruction_start() {
2903 return FIELD_ADDR(this, kHeaderSize);
2904}
2905
2906
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002907byte* Code::instruction_end() {
2908 return instruction_start() + instruction_size();
2909}
2910
2911
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002913 return RoundUp(instruction_size(), kObjectAlignment);
2914}
2915
2916
2917ByteArray* Code::unchecked_relocation_info() {
2918 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002919}
2920
2921
2922byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002923 return unchecked_relocation_info()->GetDataStartAddress();
2924}
2925
2926
2927int Code::relocation_size() {
2928 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002929}
2930
2931
2932byte* Code::entry() {
2933 return instruction_start();
2934}
2935
2936
2937bool Code::contains(byte* pc) {
2938 return (instruction_start() <= pc) &&
2939 (pc < instruction_start() + instruction_size());
2940}
2941
2942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943ACCESSORS(JSArray, length, Object, kLengthOffset)
2944
2945
ager@chromium.org236ad962008-09-25 09:45:57 +00002946ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002947
2948
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002949JSRegExp::Type JSRegExp::TypeTag() {
2950 Object* data = this->data();
2951 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2952 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2953 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002954}
2955
2956
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002957int JSRegExp::CaptureCount() {
2958 switch (TypeTag()) {
2959 case ATOM:
2960 return 0;
2961 case IRREGEXP:
2962 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2963 default:
2964 UNREACHABLE();
2965 return -1;
2966 }
2967}
2968
2969
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002970JSRegExp::Flags JSRegExp::GetFlags() {
2971 ASSERT(this->data()->IsFixedArray());
2972 Object* data = this->data();
2973 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2974 return Flags(smi->value());
2975}
2976
2977
2978String* JSRegExp::Pattern() {
2979 ASSERT(this->data()->IsFixedArray());
2980 Object* data = this->data();
2981 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2982 return pattern;
2983}
2984
2985
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002986Object* JSRegExp::DataAt(int index) {
2987 ASSERT(TypeTag() != NOT_COMPILED);
2988 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002989}
2990
2991
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002992void JSRegExp::SetDataAt(int index, Object* value) {
2993 ASSERT(TypeTag() != NOT_COMPILED);
2994 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2995 FixedArray::cast(data())->set(index, value);
2996}
2997
2998
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002999JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003000 if (map()->has_fast_elements()) {
3001 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3002 elements()->map() == Heap::fixed_cow_array_map());
3003 return FAST_ELEMENTS;
3004 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003005 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003006 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003007 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3008 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003009 ASSERT(array->IsDictionary());
3010 return DICTIONARY_ELEMENTS;
3011 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003012 if (array->IsExternalArray()) {
3013 switch (array->map()->instance_type()) {
3014 case EXTERNAL_BYTE_ARRAY_TYPE:
3015 return EXTERNAL_BYTE_ELEMENTS;
3016 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3017 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3018 case EXTERNAL_SHORT_ARRAY_TYPE:
3019 return EXTERNAL_SHORT_ELEMENTS;
3020 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3021 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3022 case EXTERNAL_INT_ARRAY_TYPE:
3023 return EXTERNAL_INT_ELEMENTS;
3024 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3025 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3026 default:
3027 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3028 return EXTERNAL_FLOAT_ELEMENTS;
3029 }
3030 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003031 ASSERT(array->IsPixelArray());
3032 return PIXEL_ELEMENTS;
3033}
3034
3035
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003036bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003037 return GetElementsKind() == FAST_ELEMENTS;
3038}
3039
3040
3041bool JSObject::HasDictionaryElements() {
3042 return GetElementsKind() == DICTIONARY_ELEMENTS;
3043}
3044
3045
3046bool JSObject::HasPixelElements() {
3047 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003048}
3049
3050
ager@chromium.org3811b432009-10-28 14:53:37 +00003051bool JSObject::HasExternalArrayElements() {
3052 return (HasExternalByteElements() ||
3053 HasExternalUnsignedByteElements() ||
3054 HasExternalShortElements() ||
3055 HasExternalUnsignedShortElements() ||
3056 HasExternalIntElements() ||
3057 HasExternalUnsignedIntElements() ||
3058 HasExternalFloatElements());
3059}
3060
3061
3062bool JSObject::HasExternalByteElements() {
3063 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3064}
3065
3066
3067bool JSObject::HasExternalUnsignedByteElements() {
3068 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3069}
3070
3071
3072bool JSObject::HasExternalShortElements() {
3073 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3074}
3075
3076
3077bool JSObject::HasExternalUnsignedShortElements() {
3078 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3079}
3080
3081
3082bool JSObject::HasExternalIntElements() {
3083 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3084}
3085
3086
3087bool JSObject::HasExternalUnsignedIntElements() {
3088 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3089}
3090
3091
3092bool JSObject::HasExternalFloatElements() {
3093 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3094}
3095
3096
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003097bool JSObject::HasNamedInterceptor() {
3098 return map()->has_named_interceptor();
3099}
3100
3101
3102bool JSObject::HasIndexedInterceptor() {
3103 return map()->has_indexed_interceptor();
3104}
3105
3106
ager@chromium.org5c838252010-02-19 08:53:10 +00003107bool JSObject::AllowsSetElementsLength() {
3108 bool result = elements()->IsFixedArray();
3109 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3110 return result;
3111}
3112
3113
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003114Object* JSObject::EnsureWritableFastElements() {
3115 ASSERT(HasFastElements());
3116 FixedArray* elems = FixedArray::cast(elements());
3117 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
3118 Object* writable_elems = Heap::CopyFixedArray(elems);
3119 if (writable_elems->IsFailure()) return writable_elems;
3120 FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
3121 set_elements(FixedArray::cast(writable_elems));
3122 Counters::cow_arrays_converted.Increment();
3123 return writable_elems;
3124}
3125
3126
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003127StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003128 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003129 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003130}
3131
3132
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003133NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003134 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003135 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003136}
3137
3138
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003139bool String::IsHashFieldComputed(uint32_t field) {
3140 return (field & kHashNotComputedMask) == 0;
3141}
3142
3143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003144bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003145 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003146}
3147
3148
3149uint32_t String::Hash() {
3150 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003151 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003152 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003153 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003154 return ComputeAndSetHash();
3155}
3156
3157
ager@chromium.org7c537e22008-10-16 08:43:32 +00003158StringHasher::StringHasher(int length)
3159 : length_(length),
3160 raw_running_hash_(0),
3161 array_index_(0),
3162 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3163 is_first_char_(true),
3164 is_valid_(true) { }
3165
3166
3167bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003168 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003169}
3170
3171
3172void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003173 // Use the Jenkins one-at-a-time hash function to update the hash
3174 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003175 raw_running_hash_ += c;
3176 raw_running_hash_ += (raw_running_hash_ << 10);
3177 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003178 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003179 if (is_array_index_) {
3180 if (c < '0' || c > '9') {
3181 is_array_index_ = false;
3182 } else {
3183 int d = c - '0';
3184 if (is_first_char_) {
3185 is_first_char_ = false;
3186 if (c == '0' && length_ > 1) {
3187 is_array_index_ = false;
3188 return;
3189 }
3190 }
3191 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3192 is_array_index_ = false;
3193 } else {
3194 array_index_ = array_index_ * 10 + d;
3195 }
3196 }
3197 }
3198}
3199
3200
3201void StringHasher::AddCharacterNoIndex(uc32 c) {
3202 ASSERT(!is_array_index());
3203 raw_running_hash_ += c;
3204 raw_running_hash_ += (raw_running_hash_ << 10);
3205 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3206}
3207
3208
3209uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003210 // Get the calculated raw hash value and do some more bit ops to distribute
3211 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003212 uint32_t result = raw_running_hash_;
3213 result += (result << 3);
3214 result ^= (result >> 11);
3215 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003216 if (result == 0) {
3217 result = 27;
3218 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003219 return result;
3220}
3221
3222
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003223bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003224 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003225 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3226 return false;
3227 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003228 return SlowAsArrayIndex(index);
3229}
3230
3231
3232Object* JSObject::GetPrototype() {
3233 return JSObject::cast(this)->map()->prototype();
3234}
3235
3236
3237PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3238 return GetPropertyAttributeWithReceiver(this, key);
3239}
3240
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003241// TODO(504): this may be useful in other places too where JSGlobalProxy
3242// is used.
3243Object* JSObject::BypassGlobalProxy() {
3244 if (IsJSGlobalProxy()) {
3245 Object* proto = GetPrototype();
3246 if (proto->IsNull()) return Heap::undefined_value();
3247 ASSERT(proto->IsJSGlobalObject());
3248 return proto;
3249 }
3250 return this;
3251}
3252
3253
3254bool JSObject::HasHiddenPropertiesObject() {
3255 ASSERT(!IsJSGlobalProxy());
3256 return GetPropertyAttributePostInterceptor(this,
3257 Heap::hidden_symbol(),
3258 false) != ABSENT;
3259}
3260
3261
3262Object* JSObject::GetHiddenPropertiesObject() {
3263 ASSERT(!IsJSGlobalProxy());
3264 PropertyAttributes attributes;
3265 return GetLocalPropertyPostInterceptor(this,
3266 Heap::hidden_symbol(),
3267 &attributes);
3268}
3269
3270
3271Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3272 ASSERT(!IsJSGlobalProxy());
3273 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3274 hidden_obj,
3275 DONT_ENUM);
3276}
3277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278
3279bool JSObject::HasElement(uint32_t index) {
3280 return HasElementWithReceiver(this, index);
3281}
3282
3283
3284bool AccessorInfo::all_can_read() {
3285 return BooleanBit::get(flag(), kAllCanReadBit);
3286}
3287
3288
3289void AccessorInfo::set_all_can_read(bool value) {
3290 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3291}
3292
3293
3294bool AccessorInfo::all_can_write() {
3295 return BooleanBit::get(flag(), kAllCanWriteBit);
3296}
3297
3298
3299void AccessorInfo::set_all_can_write(bool value) {
3300 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3301}
3302
3303
ager@chromium.org870a0b62008-11-04 11:43:05 +00003304bool AccessorInfo::prohibits_overwriting() {
3305 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3306}
3307
3308
3309void AccessorInfo::set_prohibits_overwriting(bool value) {
3310 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3311}
3312
3313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314PropertyAttributes AccessorInfo::property_attributes() {
3315 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3316}
3317
3318
3319void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3320 ASSERT(AttributesField::is_valid(attributes));
3321 int rest_value = flag()->value() & ~AttributesField::mask();
3322 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3323}
3324
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003325template<typename Shape, typename Key>
3326void Dictionary<Shape, Key>::SetEntry(int entry,
3327 Object* key,
3328 Object* value,
3329 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003330 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003331 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003332 AssertNoAllocation no_gc;
3333 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003334 FixedArray::set(index, key, mode);
3335 FixedArray::set(index+1, value, mode);
3336 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003337}
3338
3339
3340void Map::ClearCodeCache() {
3341 // No write barrier is needed since empty_fixed_array is not in new space.
3342 // Please note this function is used during marking:
3343 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003344 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3345 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003346}
3347
3348
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003349void JSArray::EnsureSize(int required_size) {
3350 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003351 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003352 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3353 if (elts->length() < required_size) {
3354 // Doubling in size would be overkill, but leave some slack to avoid
3355 // constantly growing.
3356 Expand(required_size + (required_size >> 3));
3357 // It's a performance benefit to keep a frequently used array in new-space.
3358 } else if (!Heap::new_space()->Contains(elts) &&
3359 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3360 // Expand will allocate a new backing store in new space even if the size
3361 // we asked for isn't larger than what we had before.
3362 Expand(required_size);
3363 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003364}
3365
3366
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003367void JSArray::set_length(Smi* length) {
3368 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3369}
3370
3371
ager@chromium.org7c537e22008-10-16 08:43:32 +00003372void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003373 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003374 set_elements(storage);
3375}
3376
3377
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003378Object* FixedArray::Copy() {
3379 if (length() == 0) return this;
3380 return Heap::CopyFixedArray(this);
3381}
3382
3383
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003384int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3385 return map->instance_size();
3386}
3387
3388
3389void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3390 v->VisitExternalReference(
3391 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3392}
3393
3394
3395template<typename StaticVisitor>
3396void Proxy::ProxyIterateBody() {
3397 StaticVisitor::VisitExternalReference(
3398 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3399}
3400
3401
3402void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3403 typedef v8::String::ExternalAsciiStringResource Resource;
3404 v->VisitExternalAsciiString(
3405 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3406}
3407
3408
3409template<typename StaticVisitor>
3410void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3411 typedef v8::String::ExternalAsciiStringResource Resource;
3412 StaticVisitor::VisitExternalAsciiString(
3413 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3414}
3415
3416
3417void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3418 typedef v8::String::ExternalStringResource Resource;
3419 v->VisitExternalTwoByteString(
3420 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3421}
3422
3423
3424template<typename StaticVisitor>
3425void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3426 typedef v8::String::ExternalStringResource Resource;
3427 StaticVisitor::VisitExternalTwoByteString(
3428 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3429}
3430
3431#define SLOT_ADDR(obj, offset) \
3432 reinterpret_cast<Object**>((obj)->address() + offset)
3433
3434template<int start_offset, int end_offset, int size>
3435void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3436 HeapObject* obj,
3437 ObjectVisitor* v) {
3438 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3439}
3440
3441
3442template<int start_offset>
3443void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3444 int object_size,
3445 ObjectVisitor* v) {
3446 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3447}
3448
3449#undef SLOT_ADDR
3450
3451
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452#undef CAST_ACCESSOR
3453#undef INT_ACCESSORS
3454#undef SMI_ACCESSORS
3455#undef ACCESSORS
3456#undef FIELD_ADDR
3457#undef READ_FIELD
3458#undef WRITE_FIELD
3459#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003460#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003461#undef READ_MEMADDR_FIELD
3462#undef WRITE_MEMADDR_FIELD
3463#undef READ_DOUBLE_FIELD
3464#undef WRITE_DOUBLE_FIELD
3465#undef READ_INT_FIELD
3466#undef WRITE_INT_FIELD
3467#undef READ_SHORT_FIELD
3468#undef WRITE_SHORT_FIELD
3469#undef READ_BYTE_FIELD
3470#undef WRITE_BYTE_FIELD
3471
3472
3473} } // namespace v8::internal
3474
3475#endif // V8_OBJECTS_INL_H_