blob: ab4eefa2ee215b9498a178f50d563a6ddfa2b678 [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
ricow@chromium.org65fae842010-08-25 15:26:24 +0000578bool Object::IsNormalizedMapCache() {
579 if (!IsFixedArray()) return false;
580 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
581 return false;
582 }
583#ifdef DEBUG
584 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
585#endif
586 return true;
587}
588
589
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000590bool Object::IsCompilationCacheTable() {
591 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000592}
593
594
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000595bool Object::IsCodeCacheHashTable() {
596 return IsHashTable();
597}
598
599
ager@chromium.org236ad962008-09-25 09:45:57 +0000600bool Object::IsMapCache() {
601 return IsHashTable();
602}
603
604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605bool Object::IsPrimitive() {
606 return IsOddball() || IsNumber() || IsString();
607}
608
609
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000610bool Object::IsJSGlobalProxy() {
611 bool result = IsHeapObject() &&
612 (HeapObject::cast(this)->map()->instance_type() ==
613 JS_GLOBAL_PROXY_TYPE);
614 ASSERT(!result || IsAccessCheckNeeded());
615 return result;
616}
617
618
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000620 if (!IsHeapObject()) return false;
621
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000622 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000623 return type == JS_GLOBAL_OBJECT_TYPE ||
624 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000625}
626
627
628bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000629 return IsHeapObject() &&
630 (HeapObject::cast(this)->map()->instance_type() ==
631 JS_GLOBAL_OBJECT_TYPE);
632}
633
634
635bool Object::IsJSBuiltinsObject() {
636 return IsHeapObject() &&
637 (HeapObject::cast(this)->map()->instance_type() ==
638 JS_BUILTINS_OBJECT_TYPE);
639}
640
641
642bool Object::IsUndetectableObject() {
643 return IsHeapObject()
644 && HeapObject::cast(this)->map()->is_undetectable();
645}
646
647
648bool Object::IsAccessCheckNeeded() {
649 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000650 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651}
652
653
654bool Object::IsStruct() {
655 if (!IsHeapObject()) return false;
656 switch (HeapObject::cast(this)->map()->instance_type()) {
657#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
658 STRUCT_LIST(MAKE_STRUCT_CASE)
659#undef MAKE_STRUCT_CASE
660 default: return false;
661 }
662}
663
664
665#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
666 bool Object::Is##Name() { \
667 return Object::IsHeapObject() \
668 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
669 }
670 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
671#undef MAKE_STRUCT_PREDICATE
672
673
674bool Object::IsUndefined() {
675 return this == Heap::undefined_value();
676}
677
678
679bool Object::IsTheHole() {
680 return this == Heap::the_hole_value();
681}
682
683
684bool Object::IsNull() {
685 return this == Heap::null_value();
686}
687
688
689bool Object::IsTrue() {
690 return this == Heap::true_value();
691}
692
693
694bool Object::IsFalse() {
695 return this == Heap::false_value();
696}
697
698
699double Object::Number() {
700 ASSERT(IsNumber());
701 return IsSmi()
702 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
703 : reinterpret_cast<HeapNumber*>(this)->value();
704}
705
706
707
708Object* Object::ToSmi() {
709 if (IsSmi()) return this;
710 if (IsHeapNumber()) {
711 double value = HeapNumber::cast(this)->value();
712 int int_value = FastD2I(value);
713 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
714 return Smi::FromInt(int_value);
715 }
716 }
717 return Failure::Exception();
718}
719
720
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000721bool Object::HasSpecificClassOf(String* name) {
722 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
723}
724
725
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000726Object* Object::GetElement(uint32_t index) {
727 return GetElementWithReceiver(this, index);
728}
729
730
731Object* Object::GetProperty(String* key) {
732 PropertyAttributes attributes;
733 return GetPropertyWithReceiver(this, key, &attributes);
734}
735
736
737Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
738 return GetPropertyWithReceiver(this, key, attributes);
739}
740
741
742#define FIELD_ADDR(p, offset) \
743 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
744
745#define READ_FIELD(p, offset) \
746 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
747
748#define WRITE_FIELD(p, offset, value) \
749 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
750
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000751
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752#define WRITE_BARRIER(object, offset) \
753 Heap::RecordWrite(object->address(), offset);
754
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000755// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000756// write due to the assert validating the written value.
757#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
758 if (mode == UPDATE_WRITE_BARRIER) { \
759 Heap::RecordWrite(object->address(), offset); \
760 } else { \
761 ASSERT(mode == SKIP_WRITE_BARRIER); \
762 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000763 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000764 Page::FromAddress(object->address())-> \
765 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000766 }
767
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000768#define READ_DOUBLE_FIELD(p, offset) \
769 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
770
771#define WRITE_DOUBLE_FIELD(p, offset, value) \
772 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
773
774#define READ_INT_FIELD(p, offset) \
775 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
776
777#define WRITE_INT_FIELD(p, offset, value) \
778 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
779
ager@chromium.org3e875802009-06-29 08:26:34 +0000780#define READ_INTPTR_FIELD(p, offset) \
781 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
782
783#define WRITE_INTPTR_FIELD(p, offset, value) \
784 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
785
ager@chromium.org7c537e22008-10-16 08:43:32 +0000786#define READ_UINT32_FIELD(p, offset) \
787 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
788
789#define WRITE_UINT32_FIELD(p, offset, value) \
790 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
791
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792#define READ_SHORT_FIELD(p, offset) \
793 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
794
795#define WRITE_SHORT_FIELD(p, offset, value) \
796 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
797
798#define READ_BYTE_FIELD(p, offset) \
799 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
800
801#define WRITE_BYTE_FIELD(p, offset, value) \
802 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
803
804
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000805Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
806 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000807}
808
809
810int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000811 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812}
813
814
815Smi* Smi::FromInt(int value) {
816 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000817 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000818 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000819 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000820 return reinterpret_cast<Smi*>(tagged_value);
821}
822
823
824Smi* Smi::FromIntptr(intptr_t value) {
825 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000826 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
827 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828}
829
830
831Failure::Type Failure::type() const {
832 return static_cast<Type>(value() & kFailureTypeTagMask);
833}
834
835
836bool Failure::IsInternalError() const {
837 return type() == INTERNAL_ERROR;
838}
839
840
841bool Failure::IsOutOfMemoryException() const {
842 return type() == OUT_OF_MEMORY_EXCEPTION;
843}
844
845
846int Failure::requested() const {
847 const int kShiftBits =
848 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
849 STATIC_ASSERT(kShiftBits >= 0);
850 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000851 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852}
853
854
855AllocationSpace Failure::allocation_space() const {
856 ASSERT_EQ(RETRY_AFTER_GC, type());
857 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
858 & kSpaceTagMask);
859}
860
861
862Failure* Failure::InternalError() {
863 return Construct(INTERNAL_ERROR);
864}
865
866
867Failure* Failure::Exception() {
868 return Construct(EXCEPTION);
869}
870
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000871
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000872Failure* Failure::OutOfMemoryException() {
873 return Construct(OUT_OF_MEMORY_EXCEPTION);
874}
875
876
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000877intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000878 return static_cast<intptr_t>(
879 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000880}
881
882
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000884 // Assert that the space encoding fits in the three bytes allotted for it.
885 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000886 uintptr_t requested =
887 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
888 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000889 if (((requested << tag_bits) >> tag_bits) != requested) {
890 // No room for entire requested size in the bits. Round down to
891 // maximally representable size.
892 requested = static_cast<intptr_t>(
893 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
894 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000895 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000896 return Construct(RETRY_AFTER_GC, value);
897}
898
899
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000900Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000901 uintptr_t info =
902 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000903 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000904 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905}
906
907
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000908bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909#ifdef DEBUG
910 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
911#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000912
913#ifdef V8_TARGET_ARCH_X64
914 // To be representable as a long smi, the value must be a 32-bit integer.
915 bool result = (value == static_cast<int32_t>(value));
916#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000917 // To be representable as an tagged small integer, the two
918 // most-significant bits of 'value' must be either 00 or 11 due to
919 // sign-extension. To check this we add 01 to the two
920 // most-significant bits, and check if the most-significant bit is 0
921 //
922 // CAUTION: The original code below:
923 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
924 // may lead to incorrect results according to the C language spec, and
925 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
926 // compiler may produce undefined results in case of signed integer
927 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000928 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000929#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000930 ASSERT(result == in_range);
931 return result;
932}
933
934
kasper.lund7276f142008-07-30 08:49:36 +0000935MapWord MapWord::FromMap(Map* map) {
936 return MapWord(reinterpret_cast<uintptr_t>(map));
937}
938
939
940Map* MapWord::ToMap() {
941 return reinterpret_cast<Map*>(value_);
942}
943
944
945bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000946 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000947}
948
949
950MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000951 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
952 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000953}
954
955
956HeapObject* MapWord::ToForwardingAddress() {
957 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000958 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000959}
960
961
962bool MapWord::IsMarked() {
963 return (value_ & kMarkingMask) == 0;
964}
965
966
967void MapWord::SetMark() {
968 value_ &= ~kMarkingMask;
969}
970
971
972void MapWord::ClearMark() {
973 value_ |= kMarkingMask;
974}
975
976
977bool MapWord::IsOverflowed() {
978 return (value_ & kOverflowMask) != 0;
979}
980
981
982void MapWord::SetOverflow() {
983 value_ |= kOverflowMask;
984}
985
986
987void MapWord::ClearOverflow() {
988 value_ &= ~kOverflowMask;
989}
990
991
992MapWord MapWord::EncodeAddress(Address map_address, int offset) {
993 // Offset is the distance in live bytes from the first live object in the
994 // same page. The offset between two objects in the same page should not
995 // exceed the object area size of a page.
996 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
997
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000998 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000999 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1000
1001 Page* map_page = Page::FromAddress(map_address);
1002 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1003
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001004 uintptr_t map_page_offset =
1005 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001006
1007 uintptr_t encoding =
1008 (compact_offset << kForwardingOffsetShift) |
1009 (map_page_offset << kMapPageOffsetShift) |
1010 (map_page->mc_page_index << kMapPageIndexShift);
1011 return MapWord(encoding);
1012}
1013
1014
1015Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001016 int map_page_index =
1017 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001018 ASSERT_MAP_PAGE_INDEX(map_page_index);
1019
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001020 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001021 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1022 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001023
1024 return (map_space->PageAddress(map_page_index) + map_page_offset);
1025}
1026
1027
1028int MapWord::DecodeOffset() {
1029 // The offset field is represented in the kForwardingOffsetBits
1030 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001031 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1032 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1033 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001034}
1035
1036
1037MapWord MapWord::FromEncodedAddress(Address address) {
1038 return MapWord(reinterpret_cast<uintptr_t>(address));
1039}
1040
1041
1042Address MapWord::ToEncodedAddress() {
1043 return reinterpret_cast<Address>(value_);
1044}
1045
1046
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001047#ifdef DEBUG
1048void HeapObject::VerifyObjectField(int offset) {
1049 VerifyPointer(READ_FIELD(this, offset));
1050}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001051
1052void HeapObject::VerifySmiField(int offset) {
1053 ASSERT(READ_FIELD(this, offset)->IsSmi());
1054}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055#endif
1056
1057
1058Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001059 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060}
1061
1062
1063void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001064 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065}
1066
1067
kasper.lund7276f142008-07-30 08:49:36 +00001068MapWord HeapObject::map_word() {
1069 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1070}
1071
1072
1073void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001074 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001075 // here.
1076 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1077}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001078
1079
1080HeapObject* HeapObject::FromAddress(Address address) {
1081 ASSERT_TAG_ALIGNED(address);
1082 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1083}
1084
1085
1086Address HeapObject::address() {
1087 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1088}
1089
1090
1091int HeapObject::Size() {
1092 return SizeFromMap(map());
1093}
1094
1095
1096void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1097 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1098 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1099}
1100
1101
1102void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1103 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1104}
1105
1106
kasper.lund7276f142008-07-30 08:49:36 +00001107bool HeapObject::IsMarked() {
1108 return map_word().IsMarked();
1109}
1110
1111
1112void HeapObject::SetMark() {
1113 ASSERT(!IsMarked());
1114 MapWord first_word = map_word();
1115 first_word.SetMark();
1116 set_map_word(first_word);
1117}
1118
1119
1120void HeapObject::ClearMark() {
1121 ASSERT(IsMarked());
1122 MapWord first_word = map_word();
1123 first_word.ClearMark();
1124 set_map_word(first_word);
1125}
1126
1127
1128bool HeapObject::IsOverflowed() {
1129 return map_word().IsOverflowed();
1130}
1131
1132
1133void HeapObject::SetOverflow() {
1134 MapWord first_word = map_word();
1135 first_word.SetOverflow();
1136 set_map_word(first_word);
1137}
1138
1139
1140void HeapObject::ClearOverflow() {
1141 ASSERT(IsOverflowed());
1142 MapWord first_word = map_word();
1143 first_word.ClearOverflow();
1144 set_map_word(first_word);
1145}
1146
1147
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001148double HeapNumber::value() {
1149 return READ_DOUBLE_FIELD(this, kValueOffset);
1150}
1151
1152
1153void HeapNumber::set_value(double value) {
1154 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1155}
1156
1157
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001158int HeapNumber::get_exponent() {
1159 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1160 kExponentShift) - kExponentBias;
1161}
1162
1163
1164int HeapNumber::get_sign() {
1165 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1166}
1167
1168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001169ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001170
1171
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001172HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001173 Object* array = READ_FIELD(this, kElementsOffset);
1174 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001175 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1176 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001177 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001178}
1179
1180
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001181void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001182 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001183 (value->map() == Heap::fixed_array_map() ||
1184 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001185 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001186 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1187 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001188 WRITE_FIELD(this, kElementsOffset, value);
1189 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1190}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001191
1192
1193void JSObject::initialize_properties() {
1194 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1195 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1196}
1197
1198
1199void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001200 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001201 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1202 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1203}
1204
1205
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001206Object* JSObject::ResetElements() {
1207 Object* obj = map()->GetFastElementsMap();
1208 if (obj->IsFailure()) return obj;
1209 set_map(Map::cast(obj));
1210 initialize_elements();
1211 return this;
1212}
1213
1214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001215ACCESSORS(Oddball, to_string, String, kToStringOffset)
1216ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1217
1218
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001219Object* JSGlobalPropertyCell::value() {
1220 return READ_FIELD(this, kValueOffset);
1221}
1222
1223
1224void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1225 // The write barrier is not used for global property cells.
1226 ASSERT(!val->IsJSGlobalPropertyCell());
1227 WRITE_FIELD(this, kValueOffset, val);
1228}
1229
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001230
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001231int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001232 InstanceType type = map()->instance_type();
1233 // Check for the most common kind of JavaScript object before
1234 // falling into the generic switch. This speeds up the internal
1235 // field operations considerably on average.
1236 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1237 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001238 case JS_GLOBAL_PROXY_TYPE:
1239 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001240 case JS_GLOBAL_OBJECT_TYPE:
1241 return JSGlobalObject::kSize;
1242 case JS_BUILTINS_OBJECT_TYPE:
1243 return JSBuiltinsObject::kSize;
1244 case JS_FUNCTION_TYPE:
1245 return JSFunction::kSize;
1246 case JS_VALUE_TYPE:
1247 return JSValue::kSize;
1248 case JS_ARRAY_TYPE:
1249 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001250 case JS_REGEXP_TYPE:
1251 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001252 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001253 return JSObject::kHeaderSize;
1254 default:
1255 UNREACHABLE();
1256 return 0;
1257 }
1258}
1259
1260
1261int JSObject::GetInternalFieldCount() {
1262 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001263 // Make sure to adjust for the number of in-object properties. These
1264 // properties do contribute to the size, but are not internal fields.
1265 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1266 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001267}
1268
1269
1270Object* JSObject::GetInternalField(int index) {
1271 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001272 // Internal objects do follow immediately after the header, whereas in-object
1273 // properties are at the end of the object. Therefore there is no need
1274 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1276}
1277
1278
1279void JSObject::SetInternalField(int index, Object* value) {
1280 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001281 // Internal objects do follow immediately after the header, whereas in-object
1282 // properties are at the end of the object. Therefore there is no need
1283 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001284 int offset = GetHeaderSize() + (kPointerSize * index);
1285 WRITE_FIELD(this, offset, value);
1286 WRITE_BARRIER(this, offset);
1287}
1288
1289
ager@chromium.org7c537e22008-10-16 08:43:32 +00001290// Access fast-case object properties at index. The use of these routines
1291// is needed to correctly distinguish between properties stored in-object and
1292// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001293Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001294 // Adjust for the number of properties stored in the object.
1295 index -= map()->inobject_properties();
1296 if (index < 0) {
1297 int offset = map()->instance_size() + (index * kPointerSize);
1298 return READ_FIELD(this, offset);
1299 } else {
1300 ASSERT(index < properties()->length());
1301 return properties()->get(index);
1302 }
1303}
1304
1305
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001306Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001307 // Adjust for the number of properties stored in the object.
1308 index -= map()->inobject_properties();
1309 if (index < 0) {
1310 int offset = map()->instance_size() + (index * kPointerSize);
1311 WRITE_FIELD(this, offset, value);
1312 WRITE_BARRIER(this, offset);
1313 } else {
1314 ASSERT(index < properties()->length());
1315 properties()->set(index, value);
1316 }
1317 return value;
1318}
1319
1320
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001321Object* JSObject::InObjectPropertyAt(int index) {
1322 // Adjust for the number of properties stored in the object.
1323 index -= map()->inobject_properties();
1324 ASSERT(index < 0);
1325 int offset = map()->instance_size() + (index * kPointerSize);
1326 return READ_FIELD(this, offset);
1327}
1328
1329
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001330Object* JSObject::InObjectPropertyAtPut(int index,
1331 Object* value,
1332 WriteBarrierMode mode) {
1333 // Adjust for the number of properties stored in the object.
1334 index -= map()->inobject_properties();
1335 ASSERT(index < 0);
1336 int offset = map()->instance_size() + (index * kPointerSize);
1337 WRITE_FIELD(this, offset, value);
1338 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1339 return value;
1340}
1341
1342
1343
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001344void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001345 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001347 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001348 }
1349}
1350
1351
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001352bool JSObject::HasFastProperties() {
1353 return !properties()->IsDictionary();
1354}
1355
1356
1357int JSObject::MaxFastProperties() {
1358 // Allow extra fast properties if the object has more than
1359 // kMaxFastProperties in-object properties. When this is the case,
1360 // it is very unlikely that the object is being used as a dictionary
1361 // and there is a good chance that allowing more map transitions
1362 // will be worth it.
1363 return Max(map()->inobject_properties(), kMaxFastProperties);
1364}
1365
1366
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001368 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001369 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001370 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371 }
1372}
1373
1374
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001375bool Object::ToArrayIndex(uint32_t* index) {
1376 if (IsSmi()) {
1377 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378 if (value < 0) return false;
1379 *index = value;
1380 return true;
1381 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001382 if (IsHeapNumber()) {
1383 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384 uint32_t uint_value = static_cast<uint32_t>(value);
1385 if (value == static_cast<double>(uint_value)) {
1386 *index = uint_value;
1387 return true;
1388 }
1389 }
1390 return false;
1391}
1392
1393
1394bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1395 if (!this->IsJSValue()) return false;
1396
1397 JSValue* js_value = JSValue::cast(this);
1398 if (!js_value->value()->IsString()) return false;
1399
1400 String* str = String::cast(js_value->value());
1401 if (index >= (uint32_t)str->length()) return false;
1402
1403 return true;
1404}
1405
1406
1407Object* FixedArray::get(int index) {
1408 ASSERT(index >= 0 && index < this->length());
1409 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1410}
1411
1412
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001413void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001414 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001415 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1416 int offset = kHeaderSize + index * kPointerSize;
1417 WRITE_FIELD(this, offset, value);
1418}
1419
1420
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001421void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001422 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 ASSERT(index >= 0 && index < this->length());
1424 int offset = kHeaderSize + index * kPointerSize;
1425 WRITE_FIELD(this, offset, value);
1426 WRITE_BARRIER(this, offset);
1427}
1428
1429
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001430WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1432 return UPDATE_WRITE_BARRIER;
1433}
1434
1435
1436void FixedArray::set(int index,
1437 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001438 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001439 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 ASSERT(index >= 0 && index < this->length());
1441 int offset = kHeaderSize + index * kPointerSize;
1442 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001443 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444}
1445
1446
1447void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001448 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001449 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001450 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1452}
1453
1454
1455void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001456 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001457 ASSERT(index >= 0 && index < this->length());
1458 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1459 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1460 Heap::undefined_value());
1461}
1462
1463
ager@chromium.org236ad962008-09-25 09:45:57 +00001464void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001465 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001466 ASSERT(index >= 0 && index < this->length());
1467 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1468 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1469}
1470
1471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001472void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001473 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 ASSERT(index >= 0 && index < this->length());
1475 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1476 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1477}
1478
1479
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001480void FixedArray::set_unchecked(int index, Smi* value) {
1481 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1482 int offset = kHeaderSize + index * kPointerSize;
1483 WRITE_FIELD(this, offset, value);
1484}
1485
1486
1487void FixedArray::set_null_unchecked(int index) {
1488 ASSERT(index >= 0 && index < this->length());
1489 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1490 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1491}
1492
1493
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001494Object** FixedArray::data_start() {
1495 return HeapObject::RawField(this, kHeaderSize);
1496}
1497
1498
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001499bool DescriptorArray::IsEmpty() {
1500 ASSERT(this == Heap::empty_descriptor_array() ||
1501 this->length() > 2);
1502 return this == Heap::empty_descriptor_array();
1503}
1504
1505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001506void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1507 Object* tmp = array->get(first);
1508 fast_set(array, first, array->get(second));
1509 fast_set(array, second, tmp);
1510}
1511
1512
1513int DescriptorArray::Search(String* name) {
1514 SLOW_ASSERT(IsSortedNoDuplicates());
1515
1516 // Check for empty descriptor array.
1517 int nof = number_of_descriptors();
1518 if (nof == 0) return kNotFound;
1519
1520 // Fast case: do linear search for small arrays.
1521 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001522 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001523 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001524 }
1525
1526 // Slow case: perform binary search.
1527 return BinarySearch(name, 0, nof - 1);
1528}
1529
1530
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001531int DescriptorArray::SearchWithCache(String* name) {
1532 int number = DescriptorLookupCache::Lookup(this, name);
1533 if (number == DescriptorLookupCache::kAbsent) {
1534 number = Search(name);
1535 DescriptorLookupCache::Update(this, name, number);
1536 }
1537 return number;
1538}
1539
1540
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001541String* DescriptorArray::GetKey(int descriptor_number) {
1542 ASSERT(descriptor_number < number_of_descriptors());
1543 return String::cast(get(ToKeyIndex(descriptor_number)));
1544}
1545
1546
1547Object* DescriptorArray::GetValue(int descriptor_number) {
1548 ASSERT(descriptor_number < number_of_descriptors());
1549 return GetContentArray()->get(ToValueIndex(descriptor_number));
1550}
1551
1552
1553Smi* DescriptorArray::GetDetails(int descriptor_number) {
1554 ASSERT(descriptor_number < number_of_descriptors());
1555 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1556}
1557
1558
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001559PropertyType DescriptorArray::GetType(int descriptor_number) {
1560 ASSERT(descriptor_number < number_of_descriptors());
1561 return PropertyDetails(GetDetails(descriptor_number)).type();
1562}
1563
1564
1565int DescriptorArray::GetFieldIndex(int descriptor_number) {
1566 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1567}
1568
1569
1570JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1571 return JSFunction::cast(GetValue(descriptor_number));
1572}
1573
1574
1575Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1576 ASSERT(GetType(descriptor_number) == CALLBACKS);
1577 return GetValue(descriptor_number);
1578}
1579
1580
1581AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1582 ASSERT(GetType(descriptor_number) == CALLBACKS);
1583 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1584 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1585}
1586
1587
1588bool DescriptorArray::IsProperty(int descriptor_number) {
1589 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1590}
1591
1592
1593bool DescriptorArray::IsTransition(int descriptor_number) {
1594 PropertyType t = GetType(descriptor_number);
1595 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1596}
1597
1598
1599bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1600 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1601}
1602
1603
1604bool DescriptorArray::IsDontEnum(int descriptor_number) {
1605 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1606}
1607
1608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1610 desc->Init(GetKey(descriptor_number),
1611 GetValue(descriptor_number),
1612 GetDetails(descriptor_number));
1613}
1614
1615
1616void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1617 // Range check.
1618 ASSERT(descriptor_number < number_of_descriptors());
1619
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001620 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001621 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1622 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1623
1624 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1625 FixedArray* content_array = GetContentArray();
1626 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1627 fast_set(content_array, ToDetailsIndex(descriptor_number),
1628 desc->GetDetails().AsSmi());
1629}
1630
1631
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001632void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1633 Descriptor desc;
1634 src->Get(src_index, &desc);
1635 Set(index, &desc);
1636}
1637
1638
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639void DescriptorArray::Swap(int first, int second) {
1640 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1641 FixedArray* content_array = GetContentArray();
1642 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1643 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1644}
1645
1646
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001647bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001648 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001649 if (!max_index_object->IsSmi()) return false;
1650 return 0 !=
1651 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1652}
1653
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001654uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001656 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001657 if (!max_index_object->IsSmi()) return 0;
1658 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1659 return value >> kRequiresSlowElementsTagSize;
1660}
1661
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001662void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001663 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001664}
1665
1666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667// ------------------------------------
1668// Cast operations
1669
1670
1671CAST_ACCESSOR(FixedArray)
1672CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001674CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001675CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001676CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001677CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001678CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001679CAST_ACCESSOR(String)
1680CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001681CAST_ACCESSOR(SeqAsciiString)
1682CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001683CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001684CAST_ACCESSOR(ExternalString)
1685CAST_ACCESSOR(ExternalAsciiString)
1686CAST_ACCESSOR(ExternalTwoByteString)
1687CAST_ACCESSOR(JSObject)
1688CAST_ACCESSOR(Smi)
1689CAST_ACCESSOR(Failure)
1690CAST_ACCESSOR(HeapObject)
1691CAST_ACCESSOR(HeapNumber)
1692CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001693CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694CAST_ACCESSOR(SharedFunctionInfo)
1695CAST_ACCESSOR(Map)
1696CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001697CAST_ACCESSOR(GlobalObject)
1698CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699CAST_ACCESSOR(JSGlobalObject)
1700CAST_ACCESSOR(JSBuiltinsObject)
1701CAST_ACCESSOR(Code)
1702CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001703CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001704CAST_ACCESSOR(Proxy)
1705CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001706CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001707CAST_ACCESSOR(ExternalArray)
1708CAST_ACCESSOR(ExternalByteArray)
1709CAST_ACCESSOR(ExternalUnsignedByteArray)
1710CAST_ACCESSOR(ExternalShortArray)
1711CAST_ACCESSOR(ExternalUnsignedShortArray)
1712CAST_ACCESSOR(ExternalIntArray)
1713CAST_ACCESSOR(ExternalUnsignedIntArray)
1714CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715CAST_ACCESSOR(Struct)
1716
1717
1718#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1719 STRUCT_LIST(MAKE_STRUCT_CAST)
1720#undef MAKE_STRUCT_CAST
1721
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001722
1723template <typename Shape, typename Key>
1724HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 ASSERT(obj->IsHashTable());
1726 return reinterpret_cast<HashTable*>(obj);
1727}
1728
1729
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001730SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1731SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1732
1733INT_ACCESSORS(PixelArray, length, kLengthOffset)
1734INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001735
1736
ager@chromium.orgac091b72010-05-05 07:34:42 +00001737SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001738
1739
1740uint32_t String::hash_field() {
1741 return READ_UINT32_FIELD(this, kHashFieldOffset);
1742}
1743
1744
1745void String::set_hash_field(uint32_t value) {
1746 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001747#if V8_HOST_ARCH_64_BIT
1748 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1749#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001750}
1751
1752
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753bool String::Equals(String* other) {
1754 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001755 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1756 return false;
1757 }
1758 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001759}
1760
1761
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001762Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001763 if (!StringShape(this).IsCons()) return this;
1764 ConsString* cons = ConsString::cast(this);
1765 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001766 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001767}
1768
1769
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001770String* String::TryFlattenGetString(PretenureFlag pretenure) {
1771 Object* flat = TryFlatten(pretenure);
1772 return flat->IsFailure() ? this : String::cast(flat);
1773}
1774
1775
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001776uint16_t String::Get(int index) {
1777 ASSERT(index >= 0 && index < length());
1778 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001779 case kSeqStringTag | kAsciiStringTag:
1780 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1781 case kSeqStringTag | kTwoByteStringTag:
1782 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1783 case kConsStringTag | kAsciiStringTag:
1784 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001785 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001786 case kExternalStringTag | kAsciiStringTag:
1787 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1788 case kExternalStringTag | kTwoByteStringTag:
1789 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790 default:
1791 break;
1792 }
1793
1794 UNREACHABLE();
1795 return 0;
1796}
1797
1798
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001799void String::Set(int index, uint16_t value) {
1800 ASSERT(index >= 0 && index < length());
1801 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001802
ager@chromium.org5ec48922009-05-05 07:25:34 +00001803 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001804 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1805 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806}
1807
1808
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001809bool String::IsFlat() {
1810 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001811 case kConsStringTag: {
1812 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001813 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001814 return second->length() == 0;
1815 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001816 default:
1817 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818 }
1819}
1820
1821
ager@chromium.org7c537e22008-10-16 08:43:32 +00001822uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 ASSERT(index >= 0 && index < length());
1824 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1825}
1826
1827
ager@chromium.org7c537e22008-10-16 08:43:32 +00001828void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1830 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1831 static_cast<byte>(value));
1832}
1833
1834
ager@chromium.org7c537e22008-10-16 08:43:32 +00001835Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001836 return FIELD_ADDR(this, kHeaderSize);
1837}
1838
1839
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001840char* SeqAsciiString::GetChars() {
1841 return reinterpret_cast<char*>(GetCharsAddress());
1842}
1843
1844
ager@chromium.org7c537e22008-10-16 08:43:32 +00001845Address SeqTwoByteString::GetCharsAddress() {
1846 return FIELD_ADDR(this, kHeaderSize);
1847}
1848
1849
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001850uc16* SeqTwoByteString::GetChars() {
1851 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1852}
1853
1854
ager@chromium.org7c537e22008-10-16 08:43:32 +00001855uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856 ASSERT(index >= 0 && index < length());
1857 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1858}
1859
1860
ager@chromium.org7c537e22008-10-16 08:43:32 +00001861void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862 ASSERT(index >= 0 && index < length());
1863 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1864}
1865
1866
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001867int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001868 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869}
1870
1871
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001872int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001873 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874}
1875
1876
ager@chromium.org870a0b62008-11-04 11:43:05 +00001877String* ConsString::first() {
1878 return String::cast(READ_FIELD(this, kFirstOffset));
1879}
1880
1881
1882Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883 return READ_FIELD(this, kFirstOffset);
1884}
1885
1886
ager@chromium.org870a0b62008-11-04 11:43:05 +00001887void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001889 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890}
1891
1892
ager@chromium.org870a0b62008-11-04 11:43:05 +00001893String* ConsString::second() {
1894 return String::cast(READ_FIELD(this, kSecondOffset));
1895}
1896
1897
1898Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001899 return READ_FIELD(this, kSecondOffset);
1900}
1901
1902
ager@chromium.org870a0b62008-11-04 11:43:05 +00001903void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001905 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906}
1907
1908
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1910 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1911}
1912
1913
1914void ExternalAsciiString::set_resource(
1915 ExternalAsciiString::Resource* resource) {
1916 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1917}
1918
1919
1920ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1921 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1922}
1923
1924
1925void ExternalTwoByteString::set_resource(
1926 ExternalTwoByteString::Resource* resource) {
1927 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1928}
1929
1930
ager@chromium.orgac091b72010-05-05 07:34:42 +00001931void JSFunctionResultCache::MakeZeroSize() {
1932 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1933 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1934}
1935
1936
1937void JSFunctionResultCache::Clear() {
1938 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1939 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1940 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1941 MakeZeroSize();
1942}
1943
1944
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945byte ByteArray::get(int index) {
1946 ASSERT(index >= 0 && index < this->length());
1947 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1948}
1949
1950
1951void ByteArray::set(int index, byte value) {
1952 ASSERT(index >= 0 && index < this->length());
1953 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1954}
1955
1956
1957int ByteArray::get_int(int index) {
1958 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1959 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1960}
1961
1962
1963ByteArray* ByteArray::FromDataStartAddress(Address address) {
1964 ASSERT_TAG_ALIGNED(address);
1965 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1966}
1967
1968
1969Address ByteArray::GetDataStartAddress() {
1970 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1971}
1972
1973
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001974uint8_t* PixelArray::external_pointer() {
1975 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1976 return reinterpret_cast<uint8_t*>(ptr);
1977}
1978
1979
1980void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1981 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1982 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1983}
1984
1985
1986uint8_t PixelArray::get(int index) {
1987 ASSERT((index >= 0) && (index < this->length()));
1988 uint8_t* ptr = external_pointer();
1989 return ptr[index];
1990}
1991
1992
1993void PixelArray::set(int index, uint8_t value) {
1994 ASSERT((index >= 0) && (index < this->length()));
1995 uint8_t* ptr = external_pointer();
1996 ptr[index] = value;
1997}
1998
1999
ager@chromium.org3811b432009-10-28 14:53:37 +00002000void* ExternalArray::external_pointer() {
2001 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2002 return reinterpret_cast<void*>(ptr);
2003}
2004
2005
2006void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2007 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2008 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2009}
2010
2011
2012int8_t ExternalByteArray::get(int index) {
2013 ASSERT((index >= 0) && (index < this->length()));
2014 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2015 return ptr[index];
2016}
2017
2018
2019void ExternalByteArray::set(int index, int8_t value) {
2020 ASSERT((index >= 0) && (index < this->length()));
2021 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2022 ptr[index] = value;
2023}
2024
2025
2026uint8_t ExternalUnsignedByteArray::get(int index) {
2027 ASSERT((index >= 0) && (index < this->length()));
2028 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2029 return ptr[index];
2030}
2031
2032
2033void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2034 ASSERT((index >= 0) && (index < this->length()));
2035 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2036 ptr[index] = value;
2037}
2038
2039
2040int16_t ExternalShortArray::get(int index) {
2041 ASSERT((index >= 0) && (index < this->length()));
2042 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2043 return ptr[index];
2044}
2045
2046
2047void ExternalShortArray::set(int index, int16_t value) {
2048 ASSERT((index >= 0) && (index < this->length()));
2049 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2050 ptr[index] = value;
2051}
2052
2053
2054uint16_t ExternalUnsignedShortArray::get(int index) {
2055 ASSERT((index >= 0) && (index < this->length()));
2056 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2057 return ptr[index];
2058}
2059
2060
2061void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2062 ASSERT((index >= 0) && (index < this->length()));
2063 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2064 ptr[index] = value;
2065}
2066
2067
2068int32_t ExternalIntArray::get(int index) {
2069 ASSERT((index >= 0) && (index < this->length()));
2070 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2071 return ptr[index];
2072}
2073
2074
2075void ExternalIntArray::set(int index, int32_t value) {
2076 ASSERT((index >= 0) && (index < this->length()));
2077 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2078 ptr[index] = value;
2079}
2080
2081
2082uint32_t ExternalUnsignedIntArray::get(int index) {
2083 ASSERT((index >= 0) && (index < this->length()));
2084 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2085 return ptr[index];
2086}
2087
2088
2089void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2090 ASSERT((index >= 0) && (index < this->length()));
2091 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2092 ptr[index] = value;
2093}
2094
2095
2096float ExternalFloatArray::get(int index) {
2097 ASSERT((index >= 0) && (index < this->length()));
2098 float* ptr = static_cast<float*>(external_pointer());
2099 return ptr[index];
2100}
2101
2102
2103void ExternalFloatArray::set(int index, float value) {
2104 ASSERT((index >= 0) && (index < this->length()));
2105 float* ptr = static_cast<float*>(external_pointer());
2106 ptr[index] = value;
2107}
2108
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002109
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002110INT_ACCESSORS(Map, visitor_id, kScavengerCallbackOffset)
ager@chromium.org3811b432009-10-28 14:53:37 +00002111
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002113 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2114}
2115
2116
2117int Map::inobject_properties() {
2118 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119}
2120
2121
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002122int Map::pre_allocated_property_fields() {
2123 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2124}
2125
2126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002128 int instance_size = map->instance_size();
2129 if (instance_size != kVariableSizeSentinel) return instance_size;
2130 // We can ignore the "symbol" bit becase it is only set for symbols
2131 // and implies a string type.
2132 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002133 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002135 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002137 if (instance_type == ASCII_STRING_TYPE) {
2138 return SeqAsciiString::SizeFor(
2139 reinterpret_cast<SeqAsciiString*>(this)->length());
2140 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002141 if (instance_type == BYTE_ARRAY_TYPE) {
2142 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2143 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002144 if (instance_type == STRING_TYPE) {
2145 return SeqTwoByteString::SizeFor(
2146 reinterpret_cast<SeqTwoByteString*>(this)->length());
2147 }
2148 ASSERT(instance_type == CODE_TYPE);
2149 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150}
2151
2152
2153void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002154 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002155 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156 ASSERT(0 <= value && value < 256);
2157 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2158}
2159
2160
ager@chromium.org7c537e22008-10-16 08:43:32 +00002161void Map::set_inobject_properties(int value) {
2162 ASSERT(0 <= value && value < 256);
2163 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2164}
2165
2166
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002167void Map::set_pre_allocated_property_fields(int value) {
2168 ASSERT(0 <= value && value < 256);
2169 WRITE_BYTE_FIELD(this,
2170 kPreAllocatedPropertyFieldsOffset,
2171 static_cast<byte>(value));
2172}
2173
2174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175InstanceType Map::instance_type() {
2176 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2177}
2178
2179
2180void Map::set_instance_type(InstanceType value) {
2181 ASSERT(0 <= value && value < 256);
2182 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2183}
2184
2185
2186int Map::unused_property_fields() {
2187 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2188}
2189
2190
2191void Map::set_unused_property_fields(int value) {
2192 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2193}
2194
2195
2196byte Map::bit_field() {
2197 return READ_BYTE_FIELD(this, kBitFieldOffset);
2198}
2199
2200
2201void Map::set_bit_field(byte value) {
2202 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2203}
2204
2205
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002206byte Map::bit_field2() {
2207 return READ_BYTE_FIELD(this, kBitField2Offset);
2208}
2209
2210
2211void Map::set_bit_field2(byte value) {
2212 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2213}
2214
2215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216void Map::set_non_instance_prototype(bool value) {
2217 if (value) {
2218 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2219 } else {
2220 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2221 }
2222}
2223
2224
2225bool Map::has_non_instance_prototype() {
2226 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2227}
2228
2229
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002230void Map::set_function_with_prototype(bool value) {
2231 if (value) {
2232 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2233 } else {
2234 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2235 }
2236}
2237
2238
2239bool Map::function_with_prototype() {
2240 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2241}
2242
2243
ager@chromium.org870a0b62008-11-04 11:43:05 +00002244void Map::set_is_access_check_needed(bool access_check_needed) {
2245 if (access_check_needed) {
2246 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2247 } else {
2248 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2249 }
2250}
2251
2252
2253bool Map::is_access_check_needed() {
2254 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2255}
2256
2257
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002258void Map::set_is_extensible(bool value) {
2259 if (value) {
2260 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2261 } else {
2262 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2263 }
2264}
2265
2266bool Map::is_extensible() {
2267 return ((1 << kIsExtensible) & bit_field2()) != 0;
2268}
2269
2270
2271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002272Code::Flags Code::flags() {
2273 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2274}
2275
2276
2277void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002278 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002280 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2281 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282 ExtractArgumentsCountFromFlags(flags) >= 0);
2283 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2284}
2285
2286
2287Code::Kind Code::kind() {
2288 return ExtractKindFromFlags(flags());
2289}
2290
2291
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002292InLoopFlag Code::ic_in_loop() {
2293 return ExtractICInLoopFromFlags(flags());
2294}
2295
2296
kasper.lund7276f142008-07-30 08:49:36 +00002297InlineCacheState Code::ic_state() {
2298 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299 // Only allow uninitialized or debugger states for non-IC code
2300 // objects. This is used in the debugger to determine whether or not
2301 // a call to code object has been replaced with a debug break call.
2302 ASSERT(is_inline_cache_stub() ||
2303 result == UNINITIALIZED ||
2304 result == DEBUG_BREAK ||
2305 result == DEBUG_PREPARE_STEP_IN);
2306 return result;
2307}
2308
2309
2310PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002311 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312 return ExtractTypeFromFlags(flags());
2313}
2314
2315
2316int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002317 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318 return ExtractArgumentsCountFromFlags(flags());
2319}
2320
2321
2322CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002323 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002324 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2325 kStubMajorKeyOffset));
2326}
2327
2328
2329void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002330 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002331 ASSERT(0 <= major && major < 256);
2332 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333}
2334
2335
2336bool Code::is_inline_cache_stub() {
2337 Kind kind = this->kind();
2338 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2339}
2340
2341
2342Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002343 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002344 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002345 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002346 int argc,
2347 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 // Compute the bit mask.
2349 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002350 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002351 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002352 bits |= type << kFlagsTypeShift;
2353 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002354 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002355 // Cast to flags and validate result before returning it.
2356 Flags result = static_cast<Flags>(bits);
2357 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002358 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002359 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360 ASSERT(ExtractTypeFromFlags(result) == type);
2361 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2362 return result;
2363}
2364
2365
2366Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2367 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002368 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002369 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002371 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372}
2373
2374
2375Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2376 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2377 return static_cast<Kind>(bits);
2378}
2379
2380
kasper.lund7276f142008-07-30 08:49:36 +00002381InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2382 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383 return static_cast<InlineCacheState>(bits);
2384}
2385
2386
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002387InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2388 int bits = (flags & kFlagsICInLoopMask);
2389 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2390}
2391
2392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2394 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2395 return static_cast<PropertyType>(bits);
2396}
2397
2398
2399int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2400 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2401}
2402
2403
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002404InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2405 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2406 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2407}
2408
2409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2411 int bits = flags & ~kFlagsTypeMask;
2412 return static_cast<Flags>(bits);
2413}
2414
2415
ager@chromium.org8bb60582008-12-11 12:02:20 +00002416Code* Code::GetCodeFromTargetAddress(Address address) {
2417 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2418 // GetCodeFromTargetAddress might be called when marking objects during mark
2419 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2420 // Code::cast. Code::cast does not work when the object's map is
2421 // marked.
2422 Code* result = reinterpret_cast<Code*>(code);
2423 return result;
2424}
2425
2426
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002427Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2428 return HeapObject::
2429 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2430}
2431
2432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433Object* Map::prototype() {
2434 return READ_FIELD(this, kPrototypeOffset);
2435}
2436
2437
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002438void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439 ASSERT(value->IsNull() || value->IsJSObject());
2440 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002441 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442}
2443
2444
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002445Object* Map::GetFastElementsMap() {
2446 if (has_fast_elements()) return this;
2447 Object* obj = CopyDropTransitions();
2448 if (obj->IsFailure()) return obj;
2449 Map* new_map = Map::cast(obj);
2450 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002451 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002452 return new_map;
2453}
2454
2455
2456Object* Map::GetSlowElementsMap() {
2457 if (!has_fast_elements()) return this;
2458 Object* obj = CopyDropTransitions();
2459 if (obj->IsFailure()) return obj;
2460 Map* new_map = Map::cast(obj);
2461 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002462 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002463 return new_map;
2464}
2465
2466
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467ACCESSORS(Map, instance_descriptors, DescriptorArray,
2468 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002469ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002470ACCESSORS(Map, constructor, Object, kConstructorOffset)
2471
2472ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2473ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2474
2475ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2476ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002477ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002478
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002479ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002480
2481ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2482ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2483ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2484ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2485ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002486ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002487
2488ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2489ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2490ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2491
2492ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2493ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2494ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2495ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2496ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2497ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2498
2499ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2500ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2501
2502ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2503ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2504
2505ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2506ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2508 kPropertyAccessorsOffset)
2509ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2510 kPrototypeTemplateOffset)
2511ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2512ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2513 kNamedPropertyHandlerOffset)
2514ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2515 kIndexedPropertyHandlerOffset)
2516ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2517 kInstanceTemplateOffset)
2518ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2519ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002520ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2521 kInstanceCallHandlerOffset)
2522ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2523 kAccessCheckInfoOffset)
2524ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2525
2526ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002527ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2528 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529
2530ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2531ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2532
2533ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2534
2535ACCESSORS(Script, source, Object, kSourceOffset)
2536ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002537ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002538ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2539ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002540ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002541ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002542ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2543ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002544ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002545ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002546ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002547ACCESSORS(Script, eval_from_instructions_offset, Smi,
2548 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002549
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002550#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002551ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2552ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2553ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2554ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2555
2556ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2557ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2558ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2559ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002560#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002561
2562ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002563ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002564ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2565 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002566ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2568ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002569ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002570ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2571 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002572
2573BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2574 kHiddenPrototypeBit)
2575BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2576BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2577 kNeedsAccessCheckBit)
2578BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2579 kIsExpressionBit)
2580BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2581 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002582BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002583 has_only_simple_this_property_assignments,
2584 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002585BOOL_ACCESSORS(SharedFunctionInfo,
2586 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002587 try_full_codegen,
2588 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002589BOOL_ACCESSORS(SharedFunctionInfo,
2590 compiler_hints,
2591 allows_lazy_compilation,
2592 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002593
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002594
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002595#if V8_HOST_ARCH_32_BIT
2596SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2597SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002598 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002599SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002601SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2602SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002604SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2605SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002606 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002607SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002608 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002609SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002610 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002611#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002613#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2614 int holder::name() { \
2615 int value = READ_INT_FIELD(this, offset); \
2616 ASSERT(kHeapObjectTag == 1); \
2617 ASSERT((value & kHeapObjectTag) == 0); \
2618 return value >> 1; \
2619 } \
2620 void holder::set_##name(int value) { \
2621 ASSERT(kHeapObjectTag == 1); \
2622 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2623 (value & 0xC0000000) == 0x000000000); \
2624 WRITE_INT_FIELD(this, \
2625 offset, \
2626 (value << 1) & ~kHeapObjectTag); \
2627 }
2628
2629#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2630 INT_ACCESSORS(holder, name, offset)
2631
2632
2633
2634PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2635PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2636 kFormalParameterCountOffset)
2637
2638PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2639 kExpectedNofPropertiesOffset)
2640PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2641
2642PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2643 kStartPositionAndTypeOffset)
2644PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2645
2646PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2647 kFunctionTokenPositionOffset)
2648PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2649 kCompilerHintsOffset)
2650
2651PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2652 kThisPropertyAssignmentsCountOffset)
2653#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002654
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002655ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2656ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2657
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002658bool Script::HasValidSource() {
2659 Object* src = this->source();
2660 if (!src->IsString()) return true;
2661 String* src_str = String::cast(src);
2662 if (!StringShape(src_str).IsExternal()) return true;
2663 if (src_str->IsAsciiRepresentation()) {
2664 return ExternalAsciiString::cast(src)->resource() != NULL;
2665 } else if (src_str->IsTwoByteRepresentation()) {
2666 return ExternalTwoByteString::cast(src)->resource() != NULL;
2667 }
2668 return true;
2669}
2670
2671
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002672void SharedFunctionInfo::DontAdaptArguments() {
2673 ASSERT(code()->kind() == Code::BUILTIN);
2674 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2675}
2676
2677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002678int SharedFunctionInfo::start_position() {
2679 return start_position_and_type() >> kStartPositionShift;
2680}
2681
2682
2683void SharedFunctionInfo::set_start_position(int start_position) {
2684 set_start_position_and_type((start_position << kStartPositionShift)
2685 | (start_position_and_type() & ~kStartPositionMask));
2686}
2687
2688
2689Code* SharedFunctionInfo::code() {
2690 return Code::cast(READ_FIELD(this, kCodeOffset));
2691}
2692
2693
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002694Code* SharedFunctionInfo::unchecked_code() {
2695 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2696}
2697
2698
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002699void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002701 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002702}
2703
2704
ager@chromium.orgb5737492010-07-15 09:29:43 +00002705SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2706 return reinterpret_cast<SerializedScopeInfo*>(
2707 READ_FIELD(this, kScopeInfoOffset));
2708}
2709
2710
2711void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2712 WriteBarrierMode mode) {
2713 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2714 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2715}
2716
2717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002719 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002720}
2721
2722
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002723bool SharedFunctionInfo::IsApiFunction() {
2724 return function_data()->IsFunctionTemplateInfo();
2725}
2726
2727
2728FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2729 ASSERT(IsApiFunction());
2730 return FunctionTemplateInfo::cast(function_data());
2731}
2732
2733
2734bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002735 return function_data()->IsSmi();
2736}
2737
2738
2739int SharedFunctionInfo::custom_call_generator_id() {
2740 ASSERT(HasCustomCallGenerator());
2741 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002742}
2743
2744
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002745int SharedFunctionInfo::code_age() {
2746 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2747}
2748
2749
2750void SharedFunctionInfo::set_code_age(int code_age) {
2751 set_compiler_hints(compiler_hints() |
2752 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2753}
2754
2755
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002756bool JSFunction::IsBuiltin() {
2757 return context()->global()->IsJSBuiltinsObject();
2758}
2759
2760
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002761Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002762 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763}
2764
2765
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002766Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002767 return reinterpret_cast<Code*>(
2768 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002769}
2770
2771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002772void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002773 // Skip the write barrier because code is never in new space.
2774 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002775 Address entry = value->entry();
2776 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002777}
2778
2779
2780Context* JSFunction::context() {
2781 return Context::cast(READ_FIELD(this, kContextOffset));
2782}
2783
2784
2785Object* JSFunction::unchecked_context() {
2786 return READ_FIELD(this, kContextOffset);
2787}
2788
2789
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002790SharedFunctionInfo* JSFunction::unchecked_shared() {
2791 return reinterpret_cast<SharedFunctionInfo*>(
2792 READ_FIELD(this, kSharedFunctionInfoOffset));
2793}
2794
2795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002796void JSFunction::set_context(Object* value) {
2797 ASSERT(value == Heap::undefined_value() || value->IsContext());
2798 WRITE_FIELD(this, kContextOffset, value);
2799 WRITE_BARRIER(this, kContextOffset);
2800}
2801
2802ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2803 kPrototypeOrInitialMapOffset)
2804
2805
2806Map* JSFunction::initial_map() {
2807 return Map::cast(prototype_or_initial_map());
2808}
2809
2810
2811void JSFunction::set_initial_map(Map* value) {
2812 set_prototype_or_initial_map(value);
2813}
2814
2815
2816bool JSFunction::has_initial_map() {
2817 return prototype_or_initial_map()->IsMap();
2818}
2819
2820
2821bool JSFunction::has_instance_prototype() {
2822 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2823}
2824
2825
2826bool JSFunction::has_prototype() {
2827 return map()->has_non_instance_prototype() || has_instance_prototype();
2828}
2829
2830
2831Object* JSFunction::instance_prototype() {
2832 ASSERT(has_instance_prototype());
2833 if (has_initial_map()) return initial_map()->prototype();
2834 // When there is no initial map and the prototype is a JSObject, the
2835 // initial map field is used for the prototype field.
2836 return prototype_or_initial_map();
2837}
2838
2839
2840Object* JSFunction::prototype() {
2841 ASSERT(has_prototype());
2842 // If the function's prototype property has been set to a non-JSObject
2843 // value, that value is stored in the constructor field of the map.
2844 if (map()->has_non_instance_prototype()) return map()->constructor();
2845 return instance_prototype();
2846}
2847
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002848bool JSFunction::should_have_prototype() {
2849 return map()->function_with_prototype();
2850}
2851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852
2853bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002854 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002855}
2856
2857
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002858int JSFunction::NumberOfLiterals() {
2859 return literals()->length();
2860}
2861
2862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2864 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002865 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002866}
2867
2868
2869void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2870 Object* value) {
2871 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002872 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2873 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2874}
2875
2876
2877Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2878 ASSERT(0 <= id && id < kJSBuiltinsCount);
2879 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2880}
2881
2882
2883void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2884 Code* value) {
2885 ASSERT(0 <= id && id < kJSBuiltinsCount);
2886 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2887 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002888}
2889
2890
2891Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002892 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893}
2894
2895
2896void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002897 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002898}
2899
2900
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002901ACCESSORS(JSValue, value, Object, kValueOffset)
2902
2903
2904JSValue* JSValue::cast(Object* obj) {
2905 ASSERT(obj->IsJSValue());
2906 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2907 return reinterpret_cast<JSValue*>(obj);
2908}
2909
2910
2911INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002912ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913
2914
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915byte* Code::instruction_start() {
2916 return FIELD_ADDR(this, kHeaderSize);
2917}
2918
2919
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002920byte* Code::instruction_end() {
2921 return instruction_start() + instruction_size();
2922}
2923
2924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002925int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002926 return RoundUp(instruction_size(), kObjectAlignment);
2927}
2928
2929
2930ByteArray* Code::unchecked_relocation_info() {
2931 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932}
2933
2934
2935byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002936 return unchecked_relocation_info()->GetDataStartAddress();
2937}
2938
2939
2940int Code::relocation_size() {
2941 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942}
2943
2944
2945byte* Code::entry() {
2946 return instruction_start();
2947}
2948
2949
2950bool Code::contains(byte* pc) {
2951 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00002952 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002953}
2954
2955
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002956ACCESSORS(JSArray, length, Object, kLengthOffset)
2957
2958
ager@chromium.org236ad962008-09-25 09:45:57 +00002959ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002960
2961
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002962JSRegExp::Type JSRegExp::TypeTag() {
2963 Object* data = this->data();
2964 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2965 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2966 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002967}
2968
2969
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002970int JSRegExp::CaptureCount() {
2971 switch (TypeTag()) {
2972 case ATOM:
2973 return 0;
2974 case IRREGEXP:
2975 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2976 default:
2977 UNREACHABLE();
2978 return -1;
2979 }
2980}
2981
2982
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002983JSRegExp::Flags JSRegExp::GetFlags() {
2984 ASSERT(this->data()->IsFixedArray());
2985 Object* data = this->data();
2986 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2987 return Flags(smi->value());
2988}
2989
2990
2991String* JSRegExp::Pattern() {
2992 ASSERT(this->data()->IsFixedArray());
2993 Object* data = this->data();
2994 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2995 return pattern;
2996}
2997
2998
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002999Object* JSRegExp::DataAt(int index) {
3000 ASSERT(TypeTag() != NOT_COMPILED);
3001 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003002}
3003
3004
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003005void JSRegExp::SetDataAt(int index, Object* value) {
3006 ASSERT(TypeTag() != NOT_COMPILED);
3007 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3008 FixedArray::cast(data())->set(index, value);
3009}
3010
3011
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003012JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003013 if (map()->has_fast_elements()) {
3014 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3015 elements()->map() == Heap::fixed_cow_array_map());
3016 return FAST_ELEMENTS;
3017 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003018 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003019 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003020 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3021 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003022 ASSERT(array->IsDictionary());
3023 return DICTIONARY_ELEMENTS;
3024 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003025 if (array->IsExternalArray()) {
3026 switch (array->map()->instance_type()) {
3027 case EXTERNAL_BYTE_ARRAY_TYPE:
3028 return EXTERNAL_BYTE_ELEMENTS;
3029 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3030 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3031 case EXTERNAL_SHORT_ARRAY_TYPE:
3032 return EXTERNAL_SHORT_ELEMENTS;
3033 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3034 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3035 case EXTERNAL_INT_ARRAY_TYPE:
3036 return EXTERNAL_INT_ELEMENTS;
3037 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3038 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3039 default:
3040 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3041 return EXTERNAL_FLOAT_ELEMENTS;
3042 }
3043 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003044 ASSERT(array->IsPixelArray());
3045 return PIXEL_ELEMENTS;
3046}
3047
3048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003050 return GetElementsKind() == FAST_ELEMENTS;
3051}
3052
3053
3054bool JSObject::HasDictionaryElements() {
3055 return GetElementsKind() == DICTIONARY_ELEMENTS;
3056}
3057
3058
3059bool JSObject::HasPixelElements() {
3060 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061}
3062
3063
ager@chromium.org3811b432009-10-28 14:53:37 +00003064bool JSObject::HasExternalArrayElements() {
3065 return (HasExternalByteElements() ||
3066 HasExternalUnsignedByteElements() ||
3067 HasExternalShortElements() ||
3068 HasExternalUnsignedShortElements() ||
3069 HasExternalIntElements() ||
3070 HasExternalUnsignedIntElements() ||
3071 HasExternalFloatElements());
3072}
3073
3074
3075bool JSObject::HasExternalByteElements() {
3076 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3077}
3078
3079
3080bool JSObject::HasExternalUnsignedByteElements() {
3081 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3082}
3083
3084
3085bool JSObject::HasExternalShortElements() {
3086 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3087}
3088
3089
3090bool JSObject::HasExternalUnsignedShortElements() {
3091 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3092}
3093
3094
3095bool JSObject::HasExternalIntElements() {
3096 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3097}
3098
3099
3100bool JSObject::HasExternalUnsignedIntElements() {
3101 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3102}
3103
3104
3105bool JSObject::HasExternalFloatElements() {
3106 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3107}
3108
3109
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003110bool JSObject::HasNamedInterceptor() {
3111 return map()->has_named_interceptor();
3112}
3113
3114
3115bool JSObject::HasIndexedInterceptor() {
3116 return map()->has_indexed_interceptor();
3117}
3118
3119
ager@chromium.org5c838252010-02-19 08:53:10 +00003120bool JSObject::AllowsSetElementsLength() {
3121 bool result = elements()->IsFixedArray();
3122 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3123 return result;
3124}
3125
3126
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003127Object* JSObject::EnsureWritableFastElements() {
3128 ASSERT(HasFastElements());
3129 FixedArray* elems = FixedArray::cast(elements());
3130 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
3131 Object* writable_elems = Heap::CopyFixedArray(elems);
3132 if (writable_elems->IsFailure()) return writable_elems;
3133 FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
3134 set_elements(FixedArray::cast(writable_elems));
3135 Counters::cow_arrays_converted.Increment();
3136 return writable_elems;
3137}
3138
3139
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003140StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003141 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003142 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143}
3144
3145
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003146NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003147 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003148 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003149}
3150
3151
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003152bool String::IsHashFieldComputed(uint32_t field) {
3153 return (field & kHashNotComputedMask) == 0;
3154}
3155
3156
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003157bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003158 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003159}
3160
3161
3162uint32_t String::Hash() {
3163 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003164 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003165 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003166 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003167 return ComputeAndSetHash();
3168}
3169
3170
ager@chromium.org7c537e22008-10-16 08:43:32 +00003171StringHasher::StringHasher(int length)
3172 : length_(length),
3173 raw_running_hash_(0),
3174 array_index_(0),
3175 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3176 is_first_char_(true),
3177 is_valid_(true) { }
3178
3179
3180bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003181 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003182}
3183
3184
3185void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003186 // Use the Jenkins one-at-a-time hash function to update the hash
3187 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003188 raw_running_hash_ += c;
3189 raw_running_hash_ += (raw_running_hash_ << 10);
3190 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003191 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003192 if (is_array_index_) {
3193 if (c < '0' || c > '9') {
3194 is_array_index_ = false;
3195 } else {
3196 int d = c - '0';
3197 if (is_first_char_) {
3198 is_first_char_ = false;
3199 if (c == '0' && length_ > 1) {
3200 is_array_index_ = false;
3201 return;
3202 }
3203 }
3204 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3205 is_array_index_ = false;
3206 } else {
3207 array_index_ = array_index_ * 10 + d;
3208 }
3209 }
3210 }
3211}
3212
3213
3214void StringHasher::AddCharacterNoIndex(uc32 c) {
3215 ASSERT(!is_array_index());
3216 raw_running_hash_ += c;
3217 raw_running_hash_ += (raw_running_hash_ << 10);
3218 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3219}
3220
3221
3222uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003223 // Get the calculated raw hash value and do some more bit ops to distribute
3224 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003225 uint32_t result = raw_running_hash_;
3226 result += (result << 3);
3227 result ^= (result >> 11);
3228 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003229 if (result == 0) {
3230 result = 27;
3231 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003232 return result;
3233}
3234
3235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003237 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003238 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3239 return false;
3240 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241 return SlowAsArrayIndex(index);
3242}
3243
3244
3245Object* JSObject::GetPrototype() {
3246 return JSObject::cast(this)->map()->prototype();
3247}
3248
3249
3250PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3251 return GetPropertyAttributeWithReceiver(this, key);
3252}
3253
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003254// TODO(504): this may be useful in other places too where JSGlobalProxy
3255// is used.
3256Object* JSObject::BypassGlobalProxy() {
3257 if (IsJSGlobalProxy()) {
3258 Object* proto = GetPrototype();
3259 if (proto->IsNull()) return Heap::undefined_value();
3260 ASSERT(proto->IsJSGlobalObject());
3261 return proto;
3262 }
3263 return this;
3264}
3265
3266
3267bool JSObject::HasHiddenPropertiesObject() {
3268 ASSERT(!IsJSGlobalProxy());
3269 return GetPropertyAttributePostInterceptor(this,
3270 Heap::hidden_symbol(),
3271 false) != ABSENT;
3272}
3273
3274
3275Object* JSObject::GetHiddenPropertiesObject() {
3276 ASSERT(!IsJSGlobalProxy());
3277 PropertyAttributes attributes;
3278 return GetLocalPropertyPostInterceptor(this,
3279 Heap::hidden_symbol(),
3280 &attributes);
3281}
3282
3283
3284Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3285 ASSERT(!IsJSGlobalProxy());
3286 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3287 hidden_obj,
3288 DONT_ENUM);
3289}
3290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003291
3292bool JSObject::HasElement(uint32_t index) {
3293 return HasElementWithReceiver(this, index);
3294}
3295
3296
3297bool AccessorInfo::all_can_read() {
3298 return BooleanBit::get(flag(), kAllCanReadBit);
3299}
3300
3301
3302void AccessorInfo::set_all_can_read(bool value) {
3303 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3304}
3305
3306
3307bool AccessorInfo::all_can_write() {
3308 return BooleanBit::get(flag(), kAllCanWriteBit);
3309}
3310
3311
3312void AccessorInfo::set_all_can_write(bool value) {
3313 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3314}
3315
3316
ager@chromium.org870a0b62008-11-04 11:43:05 +00003317bool AccessorInfo::prohibits_overwriting() {
3318 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3319}
3320
3321
3322void AccessorInfo::set_prohibits_overwriting(bool value) {
3323 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3324}
3325
3326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327PropertyAttributes AccessorInfo::property_attributes() {
3328 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3329}
3330
3331
3332void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3333 ASSERT(AttributesField::is_valid(attributes));
3334 int rest_value = flag()->value() & ~AttributesField::mask();
3335 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3336}
3337
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003338template<typename Shape, typename Key>
3339void Dictionary<Shape, Key>::SetEntry(int entry,
3340 Object* key,
3341 Object* value,
3342 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003343 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003344 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003345 AssertNoAllocation no_gc;
3346 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003347 FixedArray::set(index, key, mode);
3348 FixedArray::set(index+1, value, mode);
3349 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003350}
3351
3352
3353void Map::ClearCodeCache() {
3354 // No write barrier is needed since empty_fixed_array is not in new space.
3355 // Please note this function is used during marking:
3356 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003357 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3358 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003359}
3360
3361
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003362void JSArray::EnsureSize(int required_size) {
3363 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003364 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003365 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3366 if (elts->length() < required_size) {
3367 // Doubling in size would be overkill, but leave some slack to avoid
3368 // constantly growing.
3369 Expand(required_size + (required_size >> 3));
3370 // It's a performance benefit to keep a frequently used array in new-space.
3371 } else if (!Heap::new_space()->Contains(elts) &&
3372 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3373 // Expand will allocate a new backing store in new space even if the size
3374 // we asked for isn't larger than what we had before.
3375 Expand(required_size);
3376 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003377}
3378
3379
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003380void JSArray::set_length(Smi* length) {
3381 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3382}
3383
3384
ager@chromium.org7c537e22008-10-16 08:43:32 +00003385void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003386 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003387 set_elements(storage);
3388}
3389
3390
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003391Object* FixedArray::Copy() {
3392 if (length() == 0) return this;
3393 return Heap::CopyFixedArray(this);
3394}
3395
3396
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003397int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3398 return map->instance_size();
3399}
3400
3401
3402void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3403 v->VisitExternalReference(
3404 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3405}
3406
3407
3408template<typename StaticVisitor>
3409void Proxy::ProxyIterateBody() {
3410 StaticVisitor::VisitExternalReference(
3411 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3412}
3413
3414
3415void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3416 typedef v8::String::ExternalAsciiStringResource Resource;
3417 v->VisitExternalAsciiString(
3418 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3419}
3420
3421
3422template<typename StaticVisitor>
3423void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3424 typedef v8::String::ExternalAsciiStringResource Resource;
3425 StaticVisitor::VisitExternalAsciiString(
3426 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3427}
3428
3429
3430void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3431 typedef v8::String::ExternalStringResource Resource;
3432 v->VisitExternalTwoByteString(
3433 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3434}
3435
3436
3437template<typename StaticVisitor>
3438void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3439 typedef v8::String::ExternalStringResource Resource;
3440 StaticVisitor::VisitExternalTwoByteString(
3441 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3442}
3443
3444#define SLOT_ADDR(obj, offset) \
3445 reinterpret_cast<Object**>((obj)->address() + offset)
3446
3447template<int start_offset, int end_offset, int size>
3448void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3449 HeapObject* obj,
3450 ObjectVisitor* v) {
3451 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3452}
3453
3454
3455template<int start_offset>
3456void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3457 int object_size,
3458 ObjectVisitor* v) {
3459 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3460}
3461
3462#undef SLOT_ADDR
3463
3464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465#undef CAST_ACCESSOR
3466#undef INT_ACCESSORS
3467#undef SMI_ACCESSORS
3468#undef ACCESSORS
3469#undef FIELD_ADDR
3470#undef READ_FIELD
3471#undef WRITE_FIELD
3472#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003473#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474#undef READ_MEMADDR_FIELD
3475#undef WRITE_MEMADDR_FIELD
3476#undef READ_DOUBLE_FIELD
3477#undef WRITE_DOUBLE_FIELD
3478#undef READ_INT_FIELD
3479#undef WRITE_INT_FIELD
3480#undef READ_SHORT_FIELD
3481#undef WRITE_SHORT_FIELD
3482#undef READ_BYTE_FIELD
3483#undef WRITE_BYTE_FIELD
3484
3485
3486} } // namespace v8::internal
3487
3488#endif // V8_OBJECTS_INL_H_