blob: 50f4031b79cfd2aaa4f19b22ed0dcbc8435a4a16 [file] [log] [blame]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001// Copyright 2010 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
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
42#include "memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
49PropertyDetails::PropertyDetails(Smi* smi) {
50 value_ = smi->value();
51}
52
53
54Smi* PropertyDetails::AsSmi() {
55 return Smi::FromInt(value_);
56}
57
58
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000059PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000060 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000061 return PropertyDetails(smi);
62}
63
64
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000065#define CAST_ACCESSOR(type) \
66 type* type::cast(Object* object) { \
67 ASSERT(object->Is##type()); \
68 return reinterpret_cast<type*>(object); \
69 }
70
71
72#define INT_ACCESSORS(holder, name, offset) \
73 int holder::name() { return READ_INT_FIELD(this, offset); } \
74 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
75
76
77#define ACCESSORS(holder, name, type, offset) \
78 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000081 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000082 }
83
84
85#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
lrn@chromium.org303ada72010-10-27 09:33:13 +0000398bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000399 return HAS_FAILURE_TAG(this);
400}
401
402
lrn@chromium.org303ada72010-10-27 09:33:13 +0000403bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
lrn@chromium.org303ada72010-10-27 09:33:13 +0000409bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000410 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000411 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000412}
413
414
lrn@chromium.org303ada72010-10-27 09:33:13 +0000415bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000416 return this == Failure::Exception();
417}
418
419
lrn@chromium.org303ada72010-10-27 09:33:13 +0000420bool MaybeObject::IsTheHole() {
421 return this == Heap::the_hole_value();
422}
423
424
425Failure* Failure::cast(MaybeObject* obj) {
426 ASSERT(HAS_FAILURE_TAG(obj));
427 return reinterpret_cast<Failure*>(obj);
428}
429
430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431bool Object::IsJSObject() {
432 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000433 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434}
435
436
ager@chromium.org32912102009-01-16 10:38:43 +0000437bool Object::IsJSContextExtensionObject() {
438 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000439 && (HeapObject::cast(this)->map()->instance_type() ==
440 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000441}
442
443
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444bool Object::IsMap() {
445 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000446 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000447}
448
449
450bool Object::IsFixedArray() {
451 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000452 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000453}
454
455
456bool Object::IsDescriptorArray() {
457 return IsFixedArray();
458}
459
460
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000461bool Object::IsDeoptimizationInputData() {
462 // Must be a fixed array.
463 if (!IsFixedArray()) return false;
464
465 // There's no sure way to detect the difference between a fixed array and
466 // a deoptimization data array. Since this is used for asserts we can
467 // check that the length is zero or else the fixed size plus a multiple of
468 // the entry size.
469 int length = FixedArray::cast(this)->length();
470 if (length == 0) return true;
471
472 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
473 return length >= 0 &&
474 length % DeoptimizationInputData::kDeoptEntrySize == 0;
475}
476
477
478bool Object::IsDeoptimizationOutputData() {
479 if (!IsFixedArray()) return false;
480 // There's actually no way to see the difference between a fixed array and
481 // a deoptimization data array. Since this is used for asserts we can check
482 // that the length is plausible though.
483 if (FixedArray::cast(this)->length() % 2 != 0) return false;
484 return true;
485}
486
487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000488bool Object::IsContext() {
489 return Object::IsHeapObject()
490 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000491 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492 HeapObject::cast(this)->map() == Heap::global_context_map());
493}
494
495
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000496bool Object::IsCatchContext() {
497 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000498 && HeapObject::cast(this)->map() == Heap::catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000499}
500
501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502bool Object::IsGlobalContext() {
503 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000504 && HeapObject::cast(this)->map() == Heap::global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000505}
506
507
508bool Object::IsJSFunction() {
509 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000510 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000511}
512
513
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000514template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000515 return obj->IsJSFunction();
516}
517
518
519bool Object::IsCode() {
520 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000521 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522}
523
524
525bool Object::IsOddball() {
526 return Object::IsHeapObject()
527 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
528}
529
530
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000531bool Object::IsJSGlobalPropertyCell() {
532 return Object::IsHeapObject()
533 && HeapObject::cast(this)->map()->instance_type()
534 == JS_GLOBAL_PROPERTY_CELL_TYPE;
535}
536
537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538bool Object::IsSharedFunctionInfo() {
539 return Object::IsHeapObject() &&
540 (HeapObject::cast(this)->map()->instance_type() ==
541 SHARED_FUNCTION_INFO_TYPE);
542}
543
544
545bool Object::IsJSValue() {
546 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000547 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
548}
549
550
551bool Object::IsJSMessageObject() {
552 return Object::IsHeapObject()
553 && (HeapObject::cast(this)->map()->instance_type() ==
554 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000555}
556
557
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000558bool Object::IsStringWrapper() {
559 return IsJSValue() && JSValue::cast(this)->value()->IsString();
560}
561
562
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000563bool Object::IsProxy() {
564 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000565 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566}
567
568
569bool Object::IsBoolean() {
570 return IsTrue() || IsFalse();
571}
572
573
574bool Object::IsJSArray() {
575 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000576 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577}
578
579
ager@chromium.org236ad962008-09-25 09:45:57 +0000580bool Object::IsJSRegExp() {
581 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000582 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000583}
584
585
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000586template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587 return obj->IsJSArray();
588}
589
590
591bool Object::IsHashTable() {
592 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000593 && HeapObject::cast(this)->map() == Heap::hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594}
595
596
597bool Object::IsDictionary() {
598 return IsHashTable() && this != Heap::symbol_table();
599}
600
601
602bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000603 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000604}
605
606
ager@chromium.orgac091b72010-05-05 07:34:42 +0000607bool Object::IsJSFunctionResultCache() {
608 if (!IsFixedArray()) return false;
609 FixedArray* self = FixedArray::cast(this);
610 int length = self->length();
611 if (length < JSFunctionResultCache::kEntriesIndex) return false;
612 if ((length - JSFunctionResultCache::kEntriesIndex)
613 % JSFunctionResultCache::kEntrySize != 0) {
614 return false;
615 }
616#ifdef DEBUG
617 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
618#endif
619 return true;
620}
621
622
ricow@chromium.org65fae842010-08-25 15:26:24 +0000623bool Object::IsNormalizedMapCache() {
624 if (!IsFixedArray()) return false;
625 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
626 return false;
627 }
628#ifdef DEBUG
629 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
630#endif
631 return true;
632}
633
634
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000635bool Object::IsCompilationCacheTable() {
636 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000637}
638
639
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000640bool Object::IsCodeCacheHashTable() {
641 return IsHashTable();
642}
643
644
ager@chromium.org236ad962008-09-25 09:45:57 +0000645bool Object::IsMapCache() {
646 return IsHashTable();
647}
648
649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650bool Object::IsPrimitive() {
651 return IsOddball() || IsNumber() || IsString();
652}
653
654
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000655bool Object::IsJSGlobalProxy() {
656 bool result = IsHeapObject() &&
657 (HeapObject::cast(this)->map()->instance_type() ==
658 JS_GLOBAL_PROXY_TYPE);
659 ASSERT(!result || IsAccessCheckNeeded());
660 return result;
661}
662
663
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000664bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000665 if (!IsHeapObject()) return false;
666
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000667 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000668 return type == JS_GLOBAL_OBJECT_TYPE ||
669 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670}
671
672
673bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000674 return IsHeapObject() &&
675 (HeapObject::cast(this)->map()->instance_type() ==
676 JS_GLOBAL_OBJECT_TYPE);
677}
678
679
680bool Object::IsJSBuiltinsObject() {
681 return IsHeapObject() &&
682 (HeapObject::cast(this)->map()->instance_type() ==
683 JS_BUILTINS_OBJECT_TYPE);
684}
685
686
687bool Object::IsUndetectableObject() {
688 return IsHeapObject()
689 && HeapObject::cast(this)->map()->is_undetectable();
690}
691
692
693bool Object::IsAccessCheckNeeded() {
694 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000695 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696}
697
698
699bool Object::IsStruct() {
700 if (!IsHeapObject()) return false;
701 switch (HeapObject::cast(this)->map()->instance_type()) {
702#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
703 STRUCT_LIST(MAKE_STRUCT_CASE)
704#undef MAKE_STRUCT_CASE
705 default: return false;
706 }
707}
708
709
710#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
711 bool Object::Is##Name() { \
712 return Object::IsHeapObject() \
713 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
714 }
715 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
716#undef MAKE_STRUCT_PREDICATE
717
718
719bool Object::IsUndefined() {
720 return this == Heap::undefined_value();
721}
722
723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724bool Object::IsNull() {
725 return this == Heap::null_value();
726}
727
728
729bool Object::IsTrue() {
730 return this == Heap::true_value();
731}
732
733
734bool Object::IsFalse() {
735 return this == Heap::false_value();
736}
737
738
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000739bool Object::IsArgumentsMarker() {
740 return this == Heap::arguments_marker();
741}
742
743
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000744double Object::Number() {
745 ASSERT(IsNumber());
746 return IsSmi()
747 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
748 : reinterpret_cast<HeapNumber*>(this)->value();
749}
750
751
752
lrn@chromium.org303ada72010-10-27 09:33:13 +0000753MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754 if (IsSmi()) return this;
755 if (IsHeapNumber()) {
756 double value = HeapNumber::cast(this)->value();
757 int int_value = FastD2I(value);
758 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
759 return Smi::FromInt(int_value);
760 }
761 }
762 return Failure::Exception();
763}
764
765
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000766bool Object::HasSpecificClassOf(String* name) {
767 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
768}
769
770
lrn@chromium.org303ada72010-10-27 09:33:13 +0000771MaybeObject* Object::GetElement(uint32_t index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772 return GetElementWithReceiver(this, index);
773}
774
775
lrn@chromium.org303ada72010-10-27 09:33:13 +0000776Object* Object::GetElementNoExceptionThrown(uint32_t index) {
777 MaybeObject* maybe = GetElementWithReceiver(this, index);
778 ASSERT(!maybe->IsFailure());
779 Object* result = NULL; // Initialization to please compiler.
780 maybe->ToObject(&result);
781 return result;
782}
783
784
785MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786 PropertyAttributes attributes;
787 return GetPropertyWithReceiver(this, key, &attributes);
788}
789
790
lrn@chromium.org303ada72010-10-27 09:33:13 +0000791MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792 return GetPropertyWithReceiver(this, key, attributes);
793}
794
795
796#define FIELD_ADDR(p, offset) \
797 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
798
799#define READ_FIELD(p, offset) \
800 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
801
802#define WRITE_FIELD(p, offset, value) \
803 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
804
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806#define WRITE_BARRIER(object, offset) \
807 Heap::RecordWrite(object->address(), offset);
808
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000809// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000810// write due to the assert validating the written value.
811#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
812 if (mode == UPDATE_WRITE_BARRIER) { \
813 Heap::RecordWrite(object->address(), offset); \
814 } else { \
815 ASSERT(mode == SKIP_WRITE_BARRIER); \
816 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000817 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000818 Page::FromAddress(object->address())-> \
819 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000820 }
821
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822#define READ_DOUBLE_FIELD(p, offset) \
823 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
824
825#define WRITE_DOUBLE_FIELD(p, offset, value) \
826 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
827
828#define READ_INT_FIELD(p, offset) \
829 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
830
831#define WRITE_INT_FIELD(p, offset, value) \
832 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
833
ager@chromium.org3e875802009-06-29 08:26:34 +0000834#define READ_INTPTR_FIELD(p, offset) \
835 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
836
837#define WRITE_INTPTR_FIELD(p, offset, value) \
838 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
839
ager@chromium.org7c537e22008-10-16 08:43:32 +0000840#define READ_UINT32_FIELD(p, offset) \
841 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
842
843#define WRITE_UINT32_FIELD(p, offset, value) \
844 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846#define READ_SHORT_FIELD(p, offset) \
847 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
848
849#define WRITE_SHORT_FIELD(p, offset, value) \
850 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
851
852#define READ_BYTE_FIELD(p, offset) \
853 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
854
855#define WRITE_BYTE_FIELD(p, offset, value) \
856 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
857
858
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000859Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
860 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861}
862
863
864int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000865 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000866}
867
868
869Smi* Smi::FromInt(int value) {
870 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000871 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000872 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000873 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000874 return reinterpret_cast<Smi*>(tagged_value);
875}
876
877
878Smi* Smi::FromIntptr(intptr_t value) {
879 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000880 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
881 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882}
883
884
885Failure::Type Failure::type() const {
886 return static_cast<Type>(value() & kFailureTypeTagMask);
887}
888
889
890bool Failure::IsInternalError() const {
891 return type() == INTERNAL_ERROR;
892}
893
894
895bool Failure::IsOutOfMemoryException() const {
896 return type() == OUT_OF_MEMORY_EXCEPTION;
897}
898
899
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000900AllocationSpace Failure::allocation_space() const {
901 ASSERT_EQ(RETRY_AFTER_GC, type());
902 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
903 & kSpaceTagMask);
904}
905
906
907Failure* Failure::InternalError() {
908 return Construct(INTERNAL_ERROR);
909}
910
911
912Failure* Failure::Exception() {
913 return Construct(EXCEPTION);
914}
915
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000916
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000917Failure* Failure::OutOfMemoryException() {
918 return Construct(OUT_OF_MEMORY_EXCEPTION);
919}
920
921
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000922intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000923 return static_cast<intptr_t>(
924 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925}
926
927
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000928Failure* Failure::RetryAfterGC() {
929 return RetryAfterGC(NEW_SPACE);
930}
931
932
933Failure* Failure::RetryAfterGC(AllocationSpace space) {
934 ASSERT((space & ~kSpaceTagMask) == 0);
935 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000936}
937
938
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000939Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000940 uintptr_t info =
941 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000942 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000943 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000944}
945
946
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000947bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000948#ifdef DEBUG
949 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
950#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000951
952#ifdef V8_TARGET_ARCH_X64
953 // To be representable as a long smi, the value must be a 32-bit integer.
954 bool result = (value == static_cast<int32_t>(value));
955#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000956 // To be representable as an tagged small integer, the two
957 // most-significant bits of 'value' must be either 00 or 11 due to
958 // sign-extension. To check this we add 01 to the two
959 // most-significant bits, and check if the most-significant bit is 0
960 //
961 // CAUTION: The original code below:
962 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
963 // may lead to incorrect results according to the C language spec, and
964 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
965 // compiler may produce undefined results in case of signed integer
966 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000967 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000968#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000969 ASSERT(result == in_range);
970 return result;
971}
972
973
kasper.lund7276f142008-07-30 08:49:36 +0000974MapWord MapWord::FromMap(Map* map) {
975 return MapWord(reinterpret_cast<uintptr_t>(map));
976}
977
978
979Map* MapWord::ToMap() {
980 return reinterpret_cast<Map*>(value_);
981}
982
983
984bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000985 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000986}
987
988
989MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000990 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
991 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000992}
993
994
995HeapObject* MapWord::ToForwardingAddress() {
996 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000997 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000998}
999
1000
1001bool MapWord::IsMarked() {
1002 return (value_ & kMarkingMask) == 0;
1003}
1004
1005
1006void MapWord::SetMark() {
1007 value_ &= ~kMarkingMask;
1008}
1009
1010
1011void MapWord::ClearMark() {
1012 value_ |= kMarkingMask;
1013}
1014
1015
1016bool MapWord::IsOverflowed() {
1017 return (value_ & kOverflowMask) != 0;
1018}
1019
1020
1021void MapWord::SetOverflow() {
1022 value_ |= kOverflowMask;
1023}
1024
1025
1026void MapWord::ClearOverflow() {
1027 value_ &= ~kOverflowMask;
1028}
1029
1030
1031MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1032 // Offset is the distance in live bytes from the first live object in the
1033 // same page. The offset between two objects in the same page should not
1034 // exceed the object area size of a page.
1035 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1036
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001037 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001038 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1039
1040 Page* map_page = Page::FromAddress(map_address);
1041 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1042
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001043 uintptr_t map_page_offset =
1044 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001045
1046 uintptr_t encoding =
1047 (compact_offset << kForwardingOffsetShift) |
1048 (map_page_offset << kMapPageOffsetShift) |
1049 (map_page->mc_page_index << kMapPageIndexShift);
1050 return MapWord(encoding);
1051}
1052
1053
1054Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001055 int map_page_index =
1056 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001057 ASSERT_MAP_PAGE_INDEX(map_page_index);
1058
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001059 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001060 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1061 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001062
1063 return (map_space->PageAddress(map_page_index) + map_page_offset);
1064}
1065
1066
1067int MapWord::DecodeOffset() {
1068 // The offset field is represented in the kForwardingOffsetBits
1069 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001070 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1071 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1072 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001073}
1074
1075
1076MapWord MapWord::FromEncodedAddress(Address address) {
1077 return MapWord(reinterpret_cast<uintptr_t>(address));
1078}
1079
1080
1081Address MapWord::ToEncodedAddress() {
1082 return reinterpret_cast<Address>(value_);
1083}
1084
1085
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001086#ifdef DEBUG
1087void HeapObject::VerifyObjectField(int offset) {
1088 VerifyPointer(READ_FIELD(this, offset));
1089}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001090
1091void HeapObject::VerifySmiField(int offset) {
1092 ASSERT(READ_FIELD(this, offset)->IsSmi());
1093}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001094#endif
1095
1096
1097Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001098 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001099}
1100
1101
1102void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001103 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
kasper.lund7276f142008-07-30 08:49:36 +00001107MapWord HeapObject::map_word() {
1108 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1109}
1110
1111
1112void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001113 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001114 // here.
1115 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1116}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001117
1118
1119HeapObject* HeapObject::FromAddress(Address address) {
1120 ASSERT_TAG_ALIGNED(address);
1121 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1122}
1123
1124
1125Address HeapObject::address() {
1126 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1127}
1128
1129
1130int HeapObject::Size() {
1131 return SizeFromMap(map());
1132}
1133
1134
1135void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1136 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1137 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1138}
1139
1140
1141void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1142 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1143}
1144
1145
kasper.lund7276f142008-07-30 08:49:36 +00001146bool HeapObject::IsMarked() {
1147 return map_word().IsMarked();
1148}
1149
1150
1151void HeapObject::SetMark() {
1152 ASSERT(!IsMarked());
1153 MapWord first_word = map_word();
1154 first_word.SetMark();
1155 set_map_word(first_word);
1156}
1157
1158
1159void HeapObject::ClearMark() {
1160 ASSERT(IsMarked());
1161 MapWord first_word = map_word();
1162 first_word.ClearMark();
1163 set_map_word(first_word);
1164}
1165
1166
1167bool HeapObject::IsOverflowed() {
1168 return map_word().IsOverflowed();
1169}
1170
1171
1172void HeapObject::SetOverflow() {
1173 MapWord first_word = map_word();
1174 first_word.SetOverflow();
1175 set_map_word(first_word);
1176}
1177
1178
1179void HeapObject::ClearOverflow() {
1180 ASSERT(IsOverflowed());
1181 MapWord first_word = map_word();
1182 first_word.ClearOverflow();
1183 set_map_word(first_word);
1184}
1185
1186
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187double HeapNumber::value() {
1188 return READ_DOUBLE_FIELD(this, kValueOffset);
1189}
1190
1191
1192void HeapNumber::set_value(double value) {
1193 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1194}
1195
1196
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001197int HeapNumber::get_exponent() {
1198 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1199 kExponentShift) - kExponentBias;
1200}
1201
1202
1203int HeapNumber::get_sign() {
1204 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1205}
1206
1207
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001208ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001209
1210
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001211HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001212 Object* array = READ_FIELD(this, kElementsOffset);
1213 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001214 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1215 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001216 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001217}
1218
1219
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001220void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001221 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001222 (value->map() == Heap::fixed_array_map() ||
1223 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001224 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001225 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1226 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001227 WRITE_FIELD(this, kElementsOffset, value);
1228 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1229}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001230
1231
1232void JSObject::initialize_properties() {
1233 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1234 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1235}
1236
1237
1238void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001239 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001240 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1241 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1242}
1243
1244
lrn@chromium.org303ada72010-10-27 09:33:13 +00001245MaybeObject* JSObject::ResetElements() {
1246 Object* obj;
1247 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1248 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1249 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001250 set_map(Map::cast(obj));
1251 initialize_elements();
1252 return this;
1253}
1254
1255
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256ACCESSORS(Oddball, to_string, String, kToStringOffset)
1257ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1258
1259
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001260Object* JSGlobalPropertyCell::value() {
1261 return READ_FIELD(this, kValueOffset);
1262}
1263
1264
1265void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1266 // The write barrier is not used for global property cells.
1267 ASSERT(!val->IsJSGlobalPropertyCell());
1268 WRITE_FIELD(this, kValueOffset, val);
1269}
1270
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001272int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001273 InstanceType type = map()->instance_type();
1274 // Check for the most common kind of JavaScript object before
1275 // falling into the generic switch. This speeds up the internal
1276 // field operations considerably on average.
1277 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1278 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001279 case JS_GLOBAL_PROXY_TYPE:
1280 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001281 case JS_GLOBAL_OBJECT_TYPE:
1282 return JSGlobalObject::kSize;
1283 case JS_BUILTINS_OBJECT_TYPE:
1284 return JSBuiltinsObject::kSize;
1285 case JS_FUNCTION_TYPE:
1286 return JSFunction::kSize;
1287 case JS_VALUE_TYPE:
1288 return JSValue::kSize;
1289 case JS_ARRAY_TYPE:
1290 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001291 case JS_REGEXP_TYPE:
1292 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001293 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001294 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001295 case JS_MESSAGE_OBJECT_TYPE:
1296 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297 default:
1298 UNREACHABLE();
1299 return 0;
1300 }
1301}
1302
1303
1304int JSObject::GetInternalFieldCount() {
1305 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001306 // Make sure to adjust for the number of in-object properties. These
1307 // properties do contribute to the size, but are not internal fields.
1308 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1309 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001310}
1311
1312
1313Object* JSObject::GetInternalField(int index) {
1314 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001315 // Internal objects do follow immediately after the header, whereas in-object
1316 // properties are at the end of the object. Therefore there is no need
1317 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001318 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1319}
1320
1321
1322void JSObject::SetInternalField(int index, Object* value) {
1323 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001324 // Internal objects do follow immediately after the header, whereas in-object
1325 // properties are at the end of the object. Therefore there is no need
1326 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327 int offset = GetHeaderSize() + (kPointerSize * index);
1328 WRITE_FIELD(this, offset, value);
1329 WRITE_BARRIER(this, offset);
1330}
1331
1332
ager@chromium.org7c537e22008-10-16 08:43:32 +00001333// Access fast-case object properties at index. The use of these routines
1334// is needed to correctly distinguish between properties stored in-object and
1335// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001336Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001337 // Adjust for the number of properties stored in the object.
1338 index -= map()->inobject_properties();
1339 if (index < 0) {
1340 int offset = map()->instance_size() + (index * kPointerSize);
1341 return READ_FIELD(this, offset);
1342 } else {
1343 ASSERT(index < properties()->length());
1344 return properties()->get(index);
1345 }
1346}
1347
1348
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001349Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001350 // Adjust for the number of properties stored in the object.
1351 index -= map()->inobject_properties();
1352 if (index < 0) {
1353 int offset = map()->instance_size() + (index * kPointerSize);
1354 WRITE_FIELD(this, offset, value);
1355 WRITE_BARRIER(this, offset);
1356 } else {
1357 ASSERT(index < properties()->length());
1358 properties()->set(index, value);
1359 }
1360 return value;
1361}
1362
1363
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001364Object* JSObject::InObjectPropertyAt(int index) {
1365 // Adjust for the number of properties stored in the object.
1366 index -= map()->inobject_properties();
1367 ASSERT(index < 0);
1368 int offset = map()->instance_size() + (index * kPointerSize);
1369 return READ_FIELD(this, offset);
1370}
1371
1372
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001373Object* JSObject::InObjectPropertyAtPut(int index,
1374 Object* value,
1375 WriteBarrierMode mode) {
1376 // Adjust for the number of properties stored in the object.
1377 index -= map()->inobject_properties();
1378 ASSERT(index < 0);
1379 int offset = map()->instance_size() + (index * kPointerSize);
1380 WRITE_FIELD(this, offset, value);
1381 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1382 return value;
1383}
1384
1385
1386
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001387void JSObject::InitializeBody(int object_size, Object* value) {
1388 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001390 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391 }
1392}
1393
1394
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001395bool JSObject::HasFastProperties() {
1396 return !properties()->IsDictionary();
1397}
1398
1399
1400int JSObject::MaxFastProperties() {
1401 // Allow extra fast properties if the object has more than
1402 // kMaxFastProperties in-object properties. When this is the case,
1403 // it is very unlikely that the object is being used as a dictionary
1404 // and there is a good chance that allowing more map transitions
1405 // will be worth it.
1406 return Max(map()->inobject_properties(), kMaxFastProperties);
1407}
1408
1409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001411 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001412 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001413 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414 }
1415}
1416
1417
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001418bool Object::ToArrayIndex(uint32_t* index) {
1419 if (IsSmi()) {
1420 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001421 if (value < 0) return false;
1422 *index = value;
1423 return true;
1424 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001425 if (IsHeapNumber()) {
1426 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427 uint32_t uint_value = static_cast<uint32_t>(value);
1428 if (value == static_cast<double>(uint_value)) {
1429 *index = uint_value;
1430 return true;
1431 }
1432 }
1433 return false;
1434}
1435
1436
1437bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1438 if (!this->IsJSValue()) return false;
1439
1440 JSValue* js_value = JSValue::cast(this);
1441 if (!js_value->value()->IsString()) return false;
1442
1443 String* str = String::cast(js_value->value());
1444 if (index >= (uint32_t)str->length()) return false;
1445
1446 return true;
1447}
1448
1449
1450Object* FixedArray::get(int index) {
1451 ASSERT(index >= 0 && index < this->length());
1452 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1453}
1454
1455
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001456void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001457 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001458 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1459 int offset = kHeaderSize + index * kPointerSize;
1460 WRITE_FIELD(this, offset, value);
1461}
1462
1463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001465 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001466 ASSERT(index >= 0 && index < this->length());
1467 int offset = kHeaderSize + index * kPointerSize;
1468 WRITE_FIELD(this, offset, value);
1469 WRITE_BARRIER(this, offset);
1470}
1471
1472
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001473WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1475 return UPDATE_WRITE_BARRIER;
1476}
1477
1478
1479void FixedArray::set(int index,
1480 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001481 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001482 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001483 ASSERT(index >= 0 && index < this->length());
1484 int offset = kHeaderSize + index * kPointerSize;
1485 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001486 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001487}
1488
1489
1490void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001491 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001492 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001493 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1495}
1496
1497
1498void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001499 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001500 ASSERT(index >= 0 && index < this->length());
1501 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1502 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1503 Heap::undefined_value());
1504}
1505
1506
ager@chromium.org236ad962008-09-25 09:45:57 +00001507void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001508 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001509 ASSERT(index >= 0 && index < this->length());
1510 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1511 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1512}
1513
1514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001515void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001516 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001517 ASSERT(index >= 0 && index < this->length());
1518 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1519 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1520}
1521
1522
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001523void FixedArray::set_unchecked(int index, Smi* value) {
1524 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1525 int offset = kHeaderSize + index * kPointerSize;
1526 WRITE_FIELD(this, offset, value);
1527}
1528
1529
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001530void FixedArray::set_unchecked(int index,
1531 Object* value,
1532 WriteBarrierMode mode) {
1533 int offset = kHeaderSize + index * kPointerSize;
1534 WRITE_FIELD(this, offset, value);
1535 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1536}
1537
1538
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001539void FixedArray::set_null_unchecked(int index) {
1540 ASSERT(index >= 0 && index < this->length());
1541 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1542 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1543}
1544
1545
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001546Object** FixedArray::data_start() {
1547 return HeapObject::RawField(this, kHeaderSize);
1548}
1549
1550
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001551bool DescriptorArray::IsEmpty() {
1552 ASSERT(this == Heap::empty_descriptor_array() ||
1553 this->length() > 2);
1554 return this == Heap::empty_descriptor_array();
1555}
1556
1557
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1559 Object* tmp = array->get(first);
1560 fast_set(array, first, array->get(second));
1561 fast_set(array, second, tmp);
1562}
1563
1564
1565int DescriptorArray::Search(String* name) {
1566 SLOW_ASSERT(IsSortedNoDuplicates());
1567
1568 // Check for empty descriptor array.
1569 int nof = number_of_descriptors();
1570 if (nof == 0) return kNotFound;
1571
1572 // Fast case: do linear search for small arrays.
1573 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001574 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001575 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001576 }
1577
1578 // Slow case: perform binary search.
1579 return BinarySearch(name, 0, nof - 1);
1580}
1581
1582
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001583int DescriptorArray::SearchWithCache(String* name) {
1584 int number = DescriptorLookupCache::Lookup(this, name);
1585 if (number == DescriptorLookupCache::kAbsent) {
1586 number = Search(name);
1587 DescriptorLookupCache::Update(this, name, number);
1588 }
1589 return number;
1590}
1591
1592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593String* DescriptorArray::GetKey(int descriptor_number) {
1594 ASSERT(descriptor_number < number_of_descriptors());
1595 return String::cast(get(ToKeyIndex(descriptor_number)));
1596}
1597
1598
1599Object* DescriptorArray::GetValue(int descriptor_number) {
1600 ASSERT(descriptor_number < number_of_descriptors());
1601 return GetContentArray()->get(ToValueIndex(descriptor_number));
1602}
1603
1604
1605Smi* DescriptorArray::GetDetails(int descriptor_number) {
1606 ASSERT(descriptor_number < number_of_descriptors());
1607 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1608}
1609
1610
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001611PropertyType DescriptorArray::GetType(int descriptor_number) {
1612 ASSERT(descriptor_number < number_of_descriptors());
1613 return PropertyDetails(GetDetails(descriptor_number)).type();
1614}
1615
1616
1617int DescriptorArray::GetFieldIndex(int descriptor_number) {
1618 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1619}
1620
1621
1622JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1623 return JSFunction::cast(GetValue(descriptor_number));
1624}
1625
1626
1627Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1628 ASSERT(GetType(descriptor_number) == CALLBACKS);
1629 return GetValue(descriptor_number);
1630}
1631
1632
1633AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1634 ASSERT(GetType(descriptor_number) == CALLBACKS);
1635 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1636 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1637}
1638
1639
1640bool DescriptorArray::IsProperty(int descriptor_number) {
1641 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1642}
1643
1644
1645bool DescriptorArray::IsTransition(int descriptor_number) {
1646 PropertyType t = GetType(descriptor_number);
1647 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1648}
1649
1650
1651bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1652 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1653}
1654
1655
1656bool DescriptorArray::IsDontEnum(int descriptor_number) {
1657 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1658}
1659
1660
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001661void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1662 desc->Init(GetKey(descriptor_number),
1663 GetValue(descriptor_number),
1664 GetDetails(descriptor_number));
1665}
1666
1667
1668void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1669 // Range check.
1670 ASSERT(descriptor_number < number_of_descriptors());
1671
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001672 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1674 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1675
1676 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1677 FixedArray* content_array = GetContentArray();
1678 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1679 fast_set(content_array, ToDetailsIndex(descriptor_number),
1680 desc->GetDetails().AsSmi());
1681}
1682
1683
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001684void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1685 Descriptor desc;
1686 src->Get(src_index, &desc);
1687 Set(index, &desc);
1688}
1689
1690
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691void DescriptorArray::Swap(int first, int second) {
1692 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1693 FixedArray* content_array = GetContentArray();
1694 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1695 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1696}
1697
1698
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001699bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001700 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 if (!max_index_object->IsSmi()) return false;
1702 return 0 !=
1703 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1704}
1705
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001706uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001707 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001708 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001709 if (!max_index_object->IsSmi()) return 0;
1710 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1711 return value >> kRequiresSlowElementsTagSize;
1712}
1713
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001714void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001715 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001716}
1717
1718
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001719// ------------------------------------
1720// Cast operations
1721
1722
1723CAST_ACCESSOR(FixedArray)
1724CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001725CAST_ACCESSOR(DeoptimizationInputData)
1726CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001728CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001729CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001730CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001731CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001732CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733CAST_ACCESSOR(String)
1734CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001735CAST_ACCESSOR(SeqAsciiString)
1736CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001738CAST_ACCESSOR(ExternalString)
1739CAST_ACCESSOR(ExternalAsciiString)
1740CAST_ACCESSOR(ExternalTwoByteString)
1741CAST_ACCESSOR(JSObject)
1742CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743CAST_ACCESSOR(HeapObject)
1744CAST_ACCESSOR(HeapNumber)
1745CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001746CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747CAST_ACCESSOR(SharedFunctionInfo)
1748CAST_ACCESSOR(Map)
1749CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001750CAST_ACCESSOR(GlobalObject)
1751CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001752CAST_ACCESSOR(JSGlobalObject)
1753CAST_ACCESSOR(JSBuiltinsObject)
1754CAST_ACCESSOR(Code)
1755CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001756CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001757CAST_ACCESSOR(Proxy)
1758CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001759CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001760CAST_ACCESSOR(ExternalArray)
1761CAST_ACCESSOR(ExternalByteArray)
1762CAST_ACCESSOR(ExternalUnsignedByteArray)
1763CAST_ACCESSOR(ExternalShortArray)
1764CAST_ACCESSOR(ExternalUnsignedShortArray)
1765CAST_ACCESSOR(ExternalIntArray)
1766CAST_ACCESSOR(ExternalUnsignedIntArray)
1767CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768CAST_ACCESSOR(Struct)
1769
1770
1771#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1772 STRUCT_LIST(MAKE_STRUCT_CAST)
1773#undef MAKE_STRUCT_CAST
1774
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001775
1776template <typename Shape, typename Key>
1777HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778 ASSERT(obj->IsHashTable());
1779 return reinterpret_cast<HashTable*>(obj);
1780}
1781
1782
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001783SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1784SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1785
1786INT_ACCESSORS(PixelArray, length, kLengthOffset)
1787INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001788
1789
ager@chromium.orgac091b72010-05-05 07:34:42 +00001790SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001791
1792
1793uint32_t String::hash_field() {
1794 return READ_UINT32_FIELD(this, kHashFieldOffset);
1795}
1796
1797
1798void String::set_hash_field(uint32_t value) {
1799 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001800#if V8_HOST_ARCH_64_BIT
1801 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1802#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001803}
1804
1805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806bool String::Equals(String* other) {
1807 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001808 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1809 return false;
1810 }
1811 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812}
1813
1814
lrn@chromium.org303ada72010-10-27 09:33:13 +00001815MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001816 if (!StringShape(this).IsCons()) return this;
1817 ConsString* cons = ConsString::cast(this);
1818 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001819 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820}
1821
1822
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001823String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001824 MaybeObject* flat = TryFlatten(pretenure);
1825 Object* successfully_flattened;
1826 if (flat->ToObject(&successfully_flattened)) {
1827 return String::cast(successfully_flattened);
1828 }
1829 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001830}
1831
1832
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001833uint16_t String::Get(int index) {
1834 ASSERT(index >= 0 && index < length());
1835 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001836 case kSeqStringTag | kAsciiStringTag:
1837 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1838 case kSeqStringTag | kTwoByteStringTag:
1839 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1840 case kConsStringTag | kAsciiStringTag:
1841 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001842 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001843 case kExternalStringTag | kAsciiStringTag:
1844 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1845 case kExternalStringTag | kTwoByteStringTag:
1846 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001847 default:
1848 break;
1849 }
1850
1851 UNREACHABLE();
1852 return 0;
1853}
1854
1855
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001856void String::Set(int index, uint16_t value) {
1857 ASSERT(index >= 0 && index < length());
1858 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001859
ager@chromium.org5ec48922009-05-05 07:25:34 +00001860 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001861 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1862 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863}
1864
1865
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001866bool String::IsFlat() {
1867 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001868 case kConsStringTag: {
1869 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001870 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001871 return second->length() == 0;
1872 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001873 default:
1874 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875 }
1876}
1877
1878
ager@chromium.org7c537e22008-10-16 08:43:32 +00001879uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001880 ASSERT(index >= 0 && index < length());
1881 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1882}
1883
1884
ager@chromium.org7c537e22008-10-16 08:43:32 +00001885void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001886 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1887 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1888 static_cast<byte>(value));
1889}
1890
1891
ager@chromium.org7c537e22008-10-16 08:43:32 +00001892Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893 return FIELD_ADDR(this, kHeaderSize);
1894}
1895
1896
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001897char* SeqAsciiString::GetChars() {
1898 return reinterpret_cast<char*>(GetCharsAddress());
1899}
1900
1901
ager@chromium.org7c537e22008-10-16 08:43:32 +00001902Address SeqTwoByteString::GetCharsAddress() {
1903 return FIELD_ADDR(this, kHeaderSize);
1904}
1905
1906
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001907uc16* SeqTwoByteString::GetChars() {
1908 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1909}
1910
1911
ager@chromium.org7c537e22008-10-16 08:43:32 +00001912uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913 ASSERT(index >= 0 && index < length());
1914 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1915}
1916
1917
ager@chromium.org7c537e22008-10-16 08:43:32 +00001918void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001919 ASSERT(index >= 0 && index < length());
1920 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1921}
1922
1923
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001924int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001925 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926}
1927
1928
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001929int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001930 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931}
1932
1933
ager@chromium.org870a0b62008-11-04 11:43:05 +00001934String* ConsString::first() {
1935 return String::cast(READ_FIELD(this, kFirstOffset));
1936}
1937
1938
1939Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001940 return READ_FIELD(this, kFirstOffset);
1941}
1942
1943
ager@chromium.org870a0b62008-11-04 11:43:05 +00001944void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001946 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947}
1948
1949
ager@chromium.org870a0b62008-11-04 11:43:05 +00001950String* ConsString::second() {
1951 return String::cast(READ_FIELD(this, kSecondOffset));
1952}
1953
1954
1955Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956 return READ_FIELD(this, kSecondOffset);
1957}
1958
1959
ager@chromium.org870a0b62008-11-04 11:43:05 +00001960void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001961 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001962 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963}
1964
1965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001966ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1967 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1968}
1969
1970
1971void ExternalAsciiString::set_resource(
1972 ExternalAsciiString::Resource* resource) {
1973 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1974}
1975
1976
1977ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1978 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1979}
1980
1981
1982void ExternalTwoByteString::set_resource(
1983 ExternalTwoByteString::Resource* resource) {
1984 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1985}
1986
1987
ager@chromium.orgac091b72010-05-05 07:34:42 +00001988void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001989 set_finger_index(kEntriesIndex);
1990 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001991}
1992
1993
1994void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001995 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00001996 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001997 MemsetPointer(entries_start,
1998 Heap::the_hole_value(),
1999 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002000 MakeZeroSize();
2001}
2002
2003
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002004int JSFunctionResultCache::size() {
2005 return Smi::cast(get(kCacheSizeIndex))->value();
2006}
2007
2008
2009void JSFunctionResultCache::set_size(int size) {
2010 set(kCacheSizeIndex, Smi::FromInt(size));
2011}
2012
2013
2014int JSFunctionResultCache::finger_index() {
2015 return Smi::cast(get(kFingerIndex))->value();
2016}
2017
2018
2019void JSFunctionResultCache::set_finger_index(int finger_index) {
2020 set(kFingerIndex, Smi::FromInt(finger_index));
2021}
2022
2023
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024byte ByteArray::get(int index) {
2025 ASSERT(index >= 0 && index < this->length());
2026 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2027}
2028
2029
2030void ByteArray::set(int index, byte value) {
2031 ASSERT(index >= 0 && index < this->length());
2032 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2033}
2034
2035
2036int ByteArray::get_int(int index) {
2037 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2038 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2039}
2040
2041
2042ByteArray* ByteArray::FromDataStartAddress(Address address) {
2043 ASSERT_TAG_ALIGNED(address);
2044 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2045}
2046
2047
2048Address ByteArray::GetDataStartAddress() {
2049 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2050}
2051
2052
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002053uint8_t* PixelArray::external_pointer() {
2054 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2055 return reinterpret_cast<uint8_t*>(ptr);
2056}
2057
2058
2059void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
2060 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2061 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2062}
2063
2064
2065uint8_t PixelArray::get(int index) {
2066 ASSERT((index >= 0) && (index < this->length()));
2067 uint8_t* ptr = external_pointer();
2068 return ptr[index];
2069}
2070
2071
2072void PixelArray::set(int index, uint8_t value) {
2073 ASSERT((index >= 0) && (index < this->length()));
2074 uint8_t* ptr = external_pointer();
2075 ptr[index] = value;
2076}
2077
2078
ager@chromium.org3811b432009-10-28 14:53:37 +00002079void* ExternalArray::external_pointer() {
2080 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2081 return reinterpret_cast<void*>(ptr);
2082}
2083
2084
2085void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2086 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2087 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2088}
2089
2090
2091int8_t ExternalByteArray::get(int index) {
2092 ASSERT((index >= 0) && (index < this->length()));
2093 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2094 return ptr[index];
2095}
2096
2097
2098void ExternalByteArray::set(int index, int8_t value) {
2099 ASSERT((index >= 0) && (index < this->length()));
2100 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2101 ptr[index] = value;
2102}
2103
2104
2105uint8_t ExternalUnsignedByteArray::get(int index) {
2106 ASSERT((index >= 0) && (index < this->length()));
2107 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2108 return ptr[index];
2109}
2110
2111
2112void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2113 ASSERT((index >= 0) && (index < this->length()));
2114 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2115 ptr[index] = value;
2116}
2117
2118
2119int16_t ExternalShortArray::get(int index) {
2120 ASSERT((index >= 0) && (index < this->length()));
2121 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2122 return ptr[index];
2123}
2124
2125
2126void ExternalShortArray::set(int index, int16_t value) {
2127 ASSERT((index >= 0) && (index < this->length()));
2128 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2129 ptr[index] = value;
2130}
2131
2132
2133uint16_t ExternalUnsignedShortArray::get(int index) {
2134 ASSERT((index >= 0) && (index < this->length()));
2135 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2136 return ptr[index];
2137}
2138
2139
2140void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2141 ASSERT((index >= 0) && (index < this->length()));
2142 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2143 ptr[index] = value;
2144}
2145
2146
2147int32_t ExternalIntArray::get(int index) {
2148 ASSERT((index >= 0) && (index < this->length()));
2149 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2150 return ptr[index];
2151}
2152
2153
2154void ExternalIntArray::set(int index, int32_t value) {
2155 ASSERT((index >= 0) && (index < this->length()));
2156 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2157 ptr[index] = value;
2158}
2159
2160
2161uint32_t ExternalUnsignedIntArray::get(int index) {
2162 ASSERT((index >= 0) && (index < this->length()));
2163 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2164 return ptr[index];
2165}
2166
2167
2168void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2169 ASSERT((index >= 0) && (index < this->length()));
2170 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2171 ptr[index] = value;
2172}
2173
2174
2175float ExternalFloatArray::get(int index) {
2176 ASSERT((index >= 0) && (index < this->length()));
2177 float* ptr = static_cast<float*>(external_pointer());
2178 return ptr[index];
2179}
2180
2181
2182void ExternalFloatArray::set(int index, float value) {
2183 ASSERT((index >= 0) && (index < this->length()));
2184 float* ptr = static_cast<float*>(external_pointer());
2185 ptr[index] = value;
2186}
2187
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002188
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002189int Map::visitor_id() {
2190 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2191}
2192
2193
2194void Map::set_visitor_id(int id) {
2195 ASSERT(0 <= id && id < 256);
2196 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2197}
2198
ager@chromium.org3811b432009-10-28 14:53:37 +00002199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002201 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2202}
2203
2204
2205int Map::inobject_properties() {
2206 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207}
2208
2209
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002210int Map::pre_allocated_property_fields() {
2211 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2212}
2213
2214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002216 int instance_size = map->instance_size();
2217 if (instance_size != kVariableSizeSentinel) return instance_size;
2218 // We can ignore the "symbol" bit becase it is only set for symbols
2219 // and implies a string type.
2220 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002221 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002223 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002224 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002225 if (instance_type == ASCII_STRING_TYPE) {
2226 return SeqAsciiString::SizeFor(
2227 reinterpret_cast<SeqAsciiString*>(this)->length());
2228 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002229 if (instance_type == BYTE_ARRAY_TYPE) {
2230 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2231 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002232 if (instance_type == STRING_TYPE) {
2233 return SeqTwoByteString::SizeFor(
2234 reinterpret_cast<SeqTwoByteString*>(this)->length());
2235 }
2236 ASSERT(instance_type == CODE_TYPE);
2237 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002238}
2239
2240
2241void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002242 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002243 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002244 ASSERT(0 <= value && value < 256);
2245 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2246}
2247
2248
ager@chromium.org7c537e22008-10-16 08:43:32 +00002249void Map::set_inobject_properties(int value) {
2250 ASSERT(0 <= value && value < 256);
2251 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2252}
2253
2254
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002255void Map::set_pre_allocated_property_fields(int value) {
2256 ASSERT(0 <= value && value < 256);
2257 WRITE_BYTE_FIELD(this,
2258 kPreAllocatedPropertyFieldsOffset,
2259 static_cast<byte>(value));
2260}
2261
2262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002263InstanceType Map::instance_type() {
2264 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2265}
2266
2267
2268void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2270}
2271
2272
2273int Map::unused_property_fields() {
2274 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2275}
2276
2277
2278void Map::set_unused_property_fields(int value) {
2279 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2280}
2281
2282
2283byte Map::bit_field() {
2284 return READ_BYTE_FIELD(this, kBitFieldOffset);
2285}
2286
2287
2288void Map::set_bit_field(byte value) {
2289 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2290}
2291
2292
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002293byte Map::bit_field2() {
2294 return READ_BYTE_FIELD(this, kBitField2Offset);
2295}
2296
2297
2298void Map::set_bit_field2(byte value) {
2299 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2300}
2301
2302
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002303void Map::set_non_instance_prototype(bool value) {
2304 if (value) {
2305 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2306 } else {
2307 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2308 }
2309}
2310
2311
2312bool Map::has_non_instance_prototype() {
2313 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2314}
2315
2316
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002317void Map::set_function_with_prototype(bool value) {
2318 if (value) {
2319 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2320 } else {
2321 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2322 }
2323}
2324
2325
2326bool Map::function_with_prototype() {
2327 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2328}
2329
2330
ager@chromium.org870a0b62008-11-04 11:43:05 +00002331void Map::set_is_access_check_needed(bool access_check_needed) {
2332 if (access_check_needed) {
2333 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2334 } else {
2335 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2336 }
2337}
2338
2339
2340bool Map::is_access_check_needed() {
2341 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2342}
2343
2344
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002345void Map::set_is_extensible(bool value) {
2346 if (value) {
2347 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2348 } else {
2349 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2350 }
2351}
2352
2353bool Map::is_extensible() {
2354 return ((1 << kIsExtensible) & bit_field2()) != 0;
2355}
2356
2357
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002358void Map::set_attached_to_shared_function_info(bool value) {
2359 if (value) {
2360 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2361 } else {
2362 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2363 }
2364}
2365
2366bool Map::attached_to_shared_function_info() {
2367 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2368}
2369
2370
2371void Map::set_is_shared(bool value) {
2372 if (value) {
2373 set_bit_field2(bit_field2() | (1 << kIsShared));
2374 } else {
2375 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2376 }
2377}
2378
2379bool Map::is_shared() {
2380 return ((1 << kIsShared) & bit_field2()) != 0;
2381}
2382
2383
2384JSFunction* Map::unchecked_constructor() {
2385 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2386}
2387
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389Code::Flags Code::flags() {
2390 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2391}
2392
2393
2394void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002395 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002397 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2398 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399 ExtractArgumentsCountFromFlags(flags) >= 0);
2400 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2401}
2402
2403
2404Code::Kind Code::kind() {
2405 return ExtractKindFromFlags(flags());
2406}
2407
2408
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002409InLoopFlag Code::ic_in_loop() {
2410 return ExtractICInLoopFromFlags(flags());
2411}
2412
2413
kasper.lund7276f142008-07-30 08:49:36 +00002414InlineCacheState Code::ic_state() {
2415 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 // Only allow uninitialized or debugger states for non-IC code
2417 // objects. This is used in the debugger to determine whether or not
2418 // a call to code object has been replaced with a debug break call.
2419 ASSERT(is_inline_cache_stub() ||
2420 result == UNINITIALIZED ||
2421 result == DEBUG_BREAK ||
2422 result == DEBUG_PREPARE_STEP_IN);
2423 return result;
2424}
2425
2426
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002427Code::ExtraICState Code::extra_ic_state() {
2428 ASSERT(is_inline_cache_stub());
2429 return ExtractExtraICStateFromFlags(flags());
2430}
2431
2432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002434 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002435 return ExtractTypeFromFlags(flags());
2436}
2437
2438
2439int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002440 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441 return ExtractArgumentsCountFromFlags(flags());
2442}
2443
2444
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002445int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002446 ASSERT(kind() == STUB ||
2447 kind() == BINARY_OP_IC ||
2448 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2449 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002450 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002451}
2452
2453
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002454void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455 ASSERT(kind() == STUB ||
2456 kind() == BINARY_OP_IC ||
2457 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2458 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002459 ASSERT(0 <= major && major < 256);
2460 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461}
2462
2463
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002464bool Code::optimizable() {
2465 ASSERT(kind() == FUNCTION);
2466 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2467}
2468
2469
2470void Code::set_optimizable(bool value) {
2471 ASSERT(kind() == FUNCTION);
2472 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2473}
2474
2475
2476bool Code::has_deoptimization_support() {
2477 ASSERT(kind() == FUNCTION);
2478 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2479}
2480
2481
2482void Code::set_has_deoptimization_support(bool value) {
2483 ASSERT(kind() == FUNCTION);
2484 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2485}
2486
2487
2488int Code::allow_osr_at_loop_nesting_level() {
2489 ASSERT(kind() == FUNCTION);
2490 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2491}
2492
2493
2494void Code::set_allow_osr_at_loop_nesting_level(int level) {
2495 ASSERT(kind() == FUNCTION);
2496 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2497 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2498}
2499
2500
2501unsigned Code::stack_slots() {
2502 ASSERT(kind() == OPTIMIZED_FUNCTION);
2503 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2504}
2505
2506
2507void Code::set_stack_slots(unsigned slots) {
2508 ASSERT(kind() == OPTIMIZED_FUNCTION);
2509 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2510}
2511
2512
2513unsigned Code::safepoint_table_start() {
2514 ASSERT(kind() == OPTIMIZED_FUNCTION);
2515 return READ_UINT32_FIELD(this, kSafepointTableStartOffset);
2516}
2517
2518
2519void Code::set_safepoint_table_start(unsigned offset) {
2520 ASSERT(kind() == OPTIMIZED_FUNCTION);
2521 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2522 WRITE_UINT32_FIELD(this, kSafepointTableStartOffset, offset);
2523}
2524
2525
2526unsigned Code::stack_check_table_start() {
2527 ASSERT(kind() == FUNCTION);
2528 return READ_UINT32_FIELD(this, kStackCheckTableStartOffset);
2529}
2530
2531
2532void Code::set_stack_check_table_start(unsigned offset) {
2533 ASSERT(kind() == FUNCTION);
2534 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2535 WRITE_UINT32_FIELD(this, kStackCheckTableStartOffset, offset);
2536}
2537
2538
2539CheckType Code::check_type() {
2540 ASSERT(is_call_stub() || is_keyed_call_stub());
2541 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2542 return static_cast<CheckType>(type);
2543}
2544
2545
2546void Code::set_check_type(CheckType value) {
2547 ASSERT(is_call_stub() || is_keyed_call_stub());
2548 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2549}
2550
2551
2552byte Code::binary_op_type() {
2553 ASSERT(is_binary_op_stub());
2554 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2555}
2556
2557
2558void Code::set_binary_op_type(byte value) {
2559 ASSERT(is_binary_op_stub());
2560 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2561}
2562
2563
2564byte Code::type_recording_binary_op_type() {
2565 ASSERT(is_type_recording_binary_op_stub());
2566 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2567}
2568
2569
2570void Code::set_type_recording_binary_op_type(byte value) {
2571 ASSERT(is_type_recording_binary_op_stub());
2572 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2573}
2574
2575
2576byte Code::type_recording_binary_op_result_type() {
2577 ASSERT(is_type_recording_binary_op_stub());
2578 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2579}
2580
2581
2582void Code::set_type_recording_binary_op_result_type(byte value) {
2583 ASSERT(is_type_recording_binary_op_stub());
2584 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2585}
2586
2587
2588byte Code::compare_state() {
2589 ASSERT(is_compare_ic_stub());
2590 return READ_BYTE_FIELD(this, kCompareStateOffset);
2591}
2592
2593
2594void Code::set_compare_state(byte value) {
2595 ASSERT(is_compare_ic_stub());
2596 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2597}
2598
2599
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600bool Code::is_inline_cache_stub() {
2601 Kind kind = this->kind();
2602 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2603}
2604
2605
2606Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002607 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002608 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002609 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002611 int argc,
2612 InlineCacheHolderFlag holder) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002613 // Extra IC state is only allowed for monomorphic call IC stubs.
2614 ASSERT(extra_ic_state == kNoExtraICState ||
2615 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
2616 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002617 // Compute the bit mask.
2618 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002619 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002620 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002621 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002622 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002624 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002625 // Cast to flags and validate result before returning it.
2626 Flags result = static_cast<Flags>(bits);
2627 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002628 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002629 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002631 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2633 return result;
2634}
2635
2636
2637Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2638 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002639 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002640 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002641 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002642 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002643 return ComputeFlags(
2644 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002645}
2646
2647
2648Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2649 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2650 return static_cast<Kind>(bits);
2651}
2652
2653
kasper.lund7276f142008-07-30 08:49:36 +00002654InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2655 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002656 return static_cast<InlineCacheState>(bits);
2657}
2658
2659
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002660Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2661 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2662 return static_cast<ExtraICState>(bits);
2663}
2664
2665
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002666InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2667 int bits = (flags & kFlagsICInLoopMask);
2668 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2669}
2670
2671
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2673 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2674 return static_cast<PropertyType>(bits);
2675}
2676
2677
2678int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2679 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2680}
2681
2682
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002683InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2684 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2685 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2686}
2687
2688
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002689Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2690 int bits = flags & ~kFlagsTypeMask;
2691 return static_cast<Flags>(bits);
2692}
2693
2694
ager@chromium.org8bb60582008-12-11 12:02:20 +00002695Code* Code::GetCodeFromTargetAddress(Address address) {
2696 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2697 // GetCodeFromTargetAddress might be called when marking objects during mark
2698 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2699 // Code::cast. Code::cast does not work when the object's map is
2700 // marked.
2701 Code* result = reinterpret_cast<Code*>(code);
2702 return result;
2703}
2704
2705
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002706Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2707 return HeapObject::
2708 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2709}
2710
2711
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712Object* Map::prototype() {
2713 return READ_FIELD(this, kPrototypeOffset);
2714}
2715
2716
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002717void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718 ASSERT(value->IsNull() || value->IsJSObject());
2719 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002720 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002721}
2722
2723
lrn@chromium.org303ada72010-10-27 09:33:13 +00002724MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002725 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002726 Object* obj;
2727 { MaybeObject* maybe_obj = CopyDropTransitions();
2728 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2729 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002730 Map* new_map = Map::cast(obj);
2731 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002732 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002733 return new_map;
2734}
2735
2736
lrn@chromium.org303ada72010-10-27 09:33:13 +00002737MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002738 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002739 Object* obj;
2740 { MaybeObject* maybe_obj = CopyDropTransitions();
2741 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2742 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002743 Map* new_map = Map::cast(obj);
2744 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002745 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002746 return new_map;
2747}
2748
2749
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750ACCESSORS(Map, instance_descriptors, DescriptorArray,
2751 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002752ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002753ACCESSORS(Map, constructor, Object, kConstructorOffset)
2754
2755ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2756ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758
2759ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2760ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002761ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002763ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764
2765ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2766ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2767ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2768ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2769ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2770
2771ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2772ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2773ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2774
2775ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2776ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2777ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2778ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2779ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2780ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2781
2782ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2783ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2784
2785ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2786ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2787
2788ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2789ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002790ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2791 kPropertyAccessorsOffset)
2792ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2793 kPrototypeTemplateOffset)
2794ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2795ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2796 kNamedPropertyHandlerOffset)
2797ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2798 kIndexedPropertyHandlerOffset)
2799ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2800 kInstanceTemplateOffset)
2801ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2802ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2804 kInstanceCallHandlerOffset)
2805ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2806 kAccessCheckInfoOffset)
2807ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2808
2809ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002810ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2811 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812
2813ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2814ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2815
2816ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2817
2818ACCESSORS(Script, source, Object, kSourceOffset)
2819ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002820ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002821ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2822ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002823ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002824ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2826ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002827ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002828ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002829ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002830ACCESSORS(Script, eval_from_instructions_offset, Smi,
2831 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002833#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2835ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2836ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2837ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2838
2839ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2840ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2841ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2842ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002843#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002844
2845ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002846ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002847ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2849 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002850ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002851ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2852ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002853ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002854ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2855 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002856
2857BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2858 kHiddenPrototypeBit)
2859BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2860BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2861 kNeedsAccessCheckBit)
2862BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2863 kIsExpressionBit)
2864BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2865 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002866BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002867 has_only_simple_this_property_assignments,
2868 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002869BOOL_ACCESSORS(SharedFunctionInfo,
2870 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002871 try_full_codegen,
2872 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002873BOOL_ACCESSORS(SharedFunctionInfo,
2874 compiler_hints,
2875 allows_lazy_compilation,
2876 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002877
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002878
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002879#if V8_HOST_ARCH_32_BIT
2880SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2881SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002883SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002884 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002885SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2886SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002887 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002888SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2889SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002890 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002891SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002892 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002893SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002894 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002896#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002897
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002898#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002899 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002900 int holder::name() { \
2901 int value = READ_INT_FIELD(this, offset); \
2902 ASSERT(kHeapObjectTag == 1); \
2903 ASSERT((value & kHeapObjectTag) == 0); \
2904 return value >> 1; \
2905 } \
2906 void holder::set_##name(int value) { \
2907 ASSERT(kHeapObjectTag == 1); \
2908 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2909 (value & 0xC0000000) == 0x000000000); \
2910 WRITE_INT_FIELD(this, \
2911 offset, \
2912 (value << 1) & ~kHeapObjectTag); \
2913 }
2914
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002915#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2916 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002917 INT_ACCESSORS(holder, name, offset)
2918
2919
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002920PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002921PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2922 formal_parameter_count,
2923 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002924
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002925PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2926 expected_nof_properties,
2927 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002928PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2929
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002930PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
2931PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2932 start_position_and_type,
2933 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002934
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002935PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2936 function_token_position,
2937 kFunctionTokenPositionOffset)
2938PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2939 compiler_hints,
2940 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002941
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002942PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2943 this_property_assignments_count,
2944 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002946#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002947
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002948
2949int SharedFunctionInfo::construction_count() {
2950 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2951}
2952
2953
2954void SharedFunctionInfo::set_construction_count(int value) {
2955 ASSERT(0 <= value && value < 256);
2956 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2957}
2958
2959
2960bool SharedFunctionInfo::live_objects_may_exist() {
2961 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2962}
2963
2964
2965void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2966 if (value) {
2967 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2968 } else {
2969 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2970 }
2971}
2972
2973
2974bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2975 return initial_map() != Heap::undefined_value();
2976}
2977
2978
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979bool SharedFunctionInfo::optimization_disabled() {
2980 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
2981}
2982
2983
2984void SharedFunctionInfo::set_optimization_disabled(bool disable) {
2985 set_compiler_hints(BooleanBit::set(compiler_hints(),
2986 kOptimizationDisabled,
2987 disable));
2988 // If disabling optimizations we reflect that in the code object so
2989 // it will not be counted as optimizable code.
2990 if ((code()->kind() == Code::FUNCTION) && disable) {
2991 code()->set_optimizable(false);
2992 }
2993}
2994
2995
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002996ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2997ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2998
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002999bool Script::HasValidSource() {
3000 Object* src = this->source();
3001 if (!src->IsString()) return true;
3002 String* src_str = String::cast(src);
3003 if (!StringShape(src_str).IsExternal()) return true;
3004 if (src_str->IsAsciiRepresentation()) {
3005 return ExternalAsciiString::cast(src)->resource() != NULL;
3006 } else if (src_str->IsTwoByteRepresentation()) {
3007 return ExternalTwoByteString::cast(src)->resource() != NULL;
3008 }
3009 return true;
3010}
3011
3012
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003013void SharedFunctionInfo::DontAdaptArguments() {
3014 ASSERT(code()->kind() == Code::BUILTIN);
3015 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3016}
3017
3018
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003019int SharedFunctionInfo::start_position() {
3020 return start_position_and_type() >> kStartPositionShift;
3021}
3022
3023
3024void SharedFunctionInfo::set_start_position(int start_position) {
3025 set_start_position_and_type((start_position << kStartPositionShift)
3026 | (start_position_and_type() & ~kStartPositionMask));
3027}
3028
3029
3030Code* SharedFunctionInfo::code() {
3031 return Code::cast(READ_FIELD(this, kCodeOffset));
3032}
3033
3034
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003035Code* SharedFunctionInfo::unchecked_code() {
3036 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3037}
3038
3039
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003040void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003041 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003042 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043}
3044
3045
ager@chromium.orgb5737492010-07-15 09:29:43 +00003046SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3047 return reinterpret_cast<SerializedScopeInfo*>(
3048 READ_FIELD(this, kScopeInfoOffset));
3049}
3050
3051
3052void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3053 WriteBarrierMode mode) {
3054 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3055 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3056}
3057
3058
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059Smi* SharedFunctionInfo::deopt_counter() {
3060 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3061}
3062
3063
3064void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3065 WRITE_FIELD(this, kDeoptCounterOffset, value);
3066}
3067
3068
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003069bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003070 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003071}
3072
3073
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003074bool SharedFunctionInfo::IsApiFunction() {
3075 return function_data()->IsFunctionTemplateInfo();
3076}
3077
3078
3079FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3080 ASSERT(IsApiFunction());
3081 return FunctionTemplateInfo::cast(function_data());
3082}
3083
3084
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003085bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003086 return function_data()->IsSmi();
3087}
3088
3089
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003090BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3091 ASSERT(HasBuiltinFunctionId());
3092 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003093}
3094
3095
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003096int SharedFunctionInfo::code_age() {
3097 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3098}
3099
3100
3101void SharedFunctionInfo::set_code_age(int code_age) {
3102 set_compiler_hints(compiler_hints() |
3103 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3104}
3105
3106
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107bool SharedFunctionInfo::has_deoptimization_support() {
3108 Code* code = this->code();
3109 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3110}
3111
3112
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003113bool JSFunction::IsBuiltin() {
3114 return context()->global()->IsJSBuiltinsObject();
3115}
3116
3117
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118bool JSFunction::NeedsArgumentsAdaption() {
3119 return shared()->formal_parameter_count() !=
3120 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3121}
3122
3123
3124bool JSFunction::IsOptimized() {
3125 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3126}
3127
3128
3129bool JSFunction::IsMarkedForLazyRecompilation() {
3130 return code() == Builtins::builtin(Builtins::LazyRecompile);
3131}
3132
3133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003135 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003136}
3137
3138
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003139Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003140 return reinterpret_cast<Code*>(
3141 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003142}
3143
3144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003145void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003146 // Skip the write barrier because code is never in new space.
3147 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003148 Address entry = value->entry();
3149 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003150}
3151
3152
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153void JSFunction::ReplaceCode(Code* code) {
3154 bool was_optimized = IsOptimized();
3155 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3156
3157 set_code(code);
3158
3159 // Add/remove the function from the list of optimized functions for this
3160 // context based on the state change.
3161 if (!was_optimized && is_optimized) {
3162 context()->global_context()->AddOptimizedFunction(this);
3163 }
3164 if (was_optimized && !is_optimized) {
3165 context()->global_context()->RemoveOptimizedFunction(this);
3166 }
3167}
3168
3169
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170Context* JSFunction::context() {
3171 return Context::cast(READ_FIELD(this, kContextOffset));
3172}
3173
3174
3175Object* JSFunction::unchecked_context() {
3176 return READ_FIELD(this, kContextOffset);
3177}
3178
3179
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003180SharedFunctionInfo* JSFunction::unchecked_shared() {
3181 return reinterpret_cast<SharedFunctionInfo*>(
3182 READ_FIELD(this, kSharedFunctionInfoOffset));
3183}
3184
3185
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003186void JSFunction::set_context(Object* value) {
3187 ASSERT(value == Heap::undefined_value() || value->IsContext());
3188 WRITE_FIELD(this, kContextOffset, value);
3189 WRITE_BARRIER(this, kContextOffset);
3190}
3191
3192ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3193 kPrototypeOrInitialMapOffset)
3194
3195
3196Map* JSFunction::initial_map() {
3197 return Map::cast(prototype_or_initial_map());
3198}
3199
3200
3201void JSFunction::set_initial_map(Map* value) {
3202 set_prototype_or_initial_map(value);
3203}
3204
3205
3206bool JSFunction::has_initial_map() {
3207 return prototype_or_initial_map()->IsMap();
3208}
3209
3210
3211bool JSFunction::has_instance_prototype() {
3212 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3213}
3214
3215
3216bool JSFunction::has_prototype() {
3217 return map()->has_non_instance_prototype() || has_instance_prototype();
3218}
3219
3220
3221Object* JSFunction::instance_prototype() {
3222 ASSERT(has_instance_prototype());
3223 if (has_initial_map()) return initial_map()->prototype();
3224 // When there is no initial map and the prototype is a JSObject, the
3225 // initial map field is used for the prototype field.
3226 return prototype_or_initial_map();
3227}
3228
3229
3230Object* JSFunction::prototype() {
3231 ASSERT(has_prototype());
3232 // If the function's prototype property has been set to a non-JSObject
3233 // value, that value is stored in the constructor field of the map.
3234 if (map()->has_non_instance_prototype()) return map()->constructor();
3235 return instance_prototype();
3236}
3237
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003238bool JSFunction::should_have_prototype() {
3239 return map()->function_with_prototype();
3240}
3241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242
3243bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003244 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003245}
3246
3247
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003248int JSFunction::NumberOfLiterals() {
3249 return literals()->length();
3250}
3251
3252
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003253Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003254 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003255 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003256}
3257
3258
3259void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3260 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003261 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003262 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3263 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3264}
3265
3266
3267Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003268 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003269 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3270}
3271
3272
3273void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3274 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003275 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003276 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3277 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278}
3279
3280
3281Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003282 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283}
3284
3285
3286void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003287 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003288}
3289
3290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003291ACCESSORS(JSValue, value, Object, kValueOffset)
3292
3293
3294JSValue* JSValue::cast(Object* obj) {
3295 ASSERT(obj->IsJSValue());
3296 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3297 return reinterpret_cast<JSValue*>(obj);
3298}
3299
3300
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003301ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3302ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3303ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3304ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3305ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3306SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3307SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3308
3309
3310JSMessageObject* JSMessageObject::cast(Object* obj) {
3311 ASSERT(obj->IsJSMessageObject());
3312 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3313 return reinterpret_cast<JSMessageObject*>(obj);
3314}
3315
3316
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003317INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003318ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320
3321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322byte* Code::instruction_start() {
3323 return FIELD_ADDR(this, kHeaderSize);
3324}
3325
3326
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003327byte* Code::instruction_end() {
3328 return instruction_start() + instruction_size();
3329}
3330
3331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003332int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003333 return RoundUp(instruction_size(), kObjectAlignment);
3334}
3335
3336
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003337FixedArray* Code::unchecked_deoptimization_data() {
3338 return reinterpret_cast<FixedArray*>(
3339 READ_FIELD(this, kDeoptimizationDataOffset));
3340}
3341
3342
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003343ByteArray* Code::unchecked_relocation_info() {
3344 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003345}
3346
3347
3348byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003349 return unchecked_relocation_info()->GetDataStartAddress();
3350}
3351
3352
3353int Code::relocation_size() {
3354 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003355}
3356
3357
3358byte* Code::entry() {
3359 return instruction_start();
3360}
3361
3362
3363bool Code::contains(byte* pc) {
3364 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003365 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366}
3367
3368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369ACCESSORS(JSArray, length, Object, kLengthOffset)
3370
3371
ager@chromium.org236ad962008-09-25 09:45:57 +00003372ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003373
3374
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003375JSRegExp::Type JSRegExp::TypeTag() {
3376 Object* data = this->data();
3377 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3378 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3379 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003380}
3381
3382
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003383int JSRegExp::CaptureCount() {
3384 switch (TypeTag()) {
3385 case ATOM:
3386 return 0;
3387 case IRREGEXP:
3388 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3389 default:
3390 UNREACHABLE();
3391 return -1;
3392 }
3393}
3394
3395
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003396JSRegExp::Flags JSRegExp::GetFlags() {
3397 ASSERT(this->data()->IsFixedArray());
3398 Object* data = this->data();
3399 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3400 return Flags(smi->value());
3401}
3402
3403
3404String* JSRegExp::Pattern() {
3405 ASSERT(this->data()->IsFixedArray());
3406 Object* data = this->data();
3407 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3408 return pattern;
3409}
3410
3411
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003412Object* JSRegExp::DataAt(int index) {
3413 ASSERT(TypeTag() != NOT_COMPILED);
3414 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003415}
3416
3417
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003418void JSRegExp::SetDataAt(int index, Object* value) {
3419 ASSERT(TypeTag() != NOT_COMPILED);
3420 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3421 FixedArray::cast(data())->set(index, value);
3422}
3423
3424
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003425JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003426 if (map()->has_fast_elements()) {
3427 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3428 elements()->map() == Heap::fixed_cow_array_map());
3429 return FAST_ELEMENTS;
3430 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003431 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003432 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003433 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3434 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003435 ASSERT(array->IsDictionary());
3436 return DICTIONARY_ELEMENTS;
3437 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003438 if (array->IsExternalArray()) {
3439 switch (array->map()->instance_type()) {
3440 case EXTERNAL_BYTE_ARRAY_TYPE:
3441 return EXTERNAL_BYTE_ELEMENTS;
3442 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3443 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3444 case EXTERNAL_SHORT_ARRAY_TYPE:
3445 return EXTERNAL_SHORT_ELEMENTS;
3446 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3447 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3448 case EXTERNAL_INT_ARRAY_TYPE:
3449 return EXTERNAL_INT_ELEMENTS;
3450 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3451 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3452 default:
3453 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3454 return EXTERNAL_FLOAT_ELEMENTS;
3455 }
3456 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003457 ASSERT(array->IsPixelArray());
3458 return PIXEL_ELEMENTS;
3459}
3460
3461
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003463 return GetElementsKind() == FAST_ELEMENTS;
3464}
3465
3466
3467bool JSObject::HasDictionaryElements() {
3468 return GetElementsKind() == DICTIONARY_ELEMENTS;
3469}
3470
3471
3472bool JSObject::HasPixelElements() {
3473 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474}
3475
3476
ager@chromium.org3811b432009-10-28 14:53:37 +00003477bool JSObject::HasExternalArrayElements() {
3478 return (HasExternalByteElements() ||
3479 HasExternalUnsignedByteElements() ||
3480 HasExternalShortElements() ||
3481 HasExternalUnsignedShortElements() ||
3482 HasExternalIntElements() ||
3483 HasExternalUnsignedIntElements() ||
3484 HasExternalFloatElements());
3485}
3486
3487
3488bool JSObject::HasExternalByteElements() {
3489 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3490}
3491
3492
3493bool JSObject::HasExternalUnsignedByteElements() {
3494 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3495}
3496
3497
3498bool JSObject::HasExternalShortElements() {
3499 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3500}
3501
3502
3503bool JSObject::HasExternalUnsignedShortElements() {
3504 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3505}
3506
3507
3508bool JSObject::HasExternalIntElements() {
3509 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3510}
3511
3512
3513bool JSObject::HasExternalUnsignedIntElements() {
3514 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3515}
3516
3517
3518bool JSObject::HasExternalFloatElements() {
3519 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3520}
3521
3522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003523bool JSObject::HasNamedInterceptor() {
3524 return map()->has_named_interceptor();
3525}
3526
3527
3528bool JSObject::HasIndexedInterceptor() {
3529 return map()->has_indexed_interceptor();
3530}
3531
3532
ager@chromium.org5c838252010-02-19 08:53:10 +00003533bool JSObject::AllowsSetElementsLength() {
3534 bool result = elements()->IsFixedArray();
3535 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3536 return result;
3537}
3538
3539
lrn@chromium.org303ada72010-10-27 09:33:13 +00003540MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003541 ASSERT(HasFastElements());
3542 FixedArray* elems = FixedArray::cast(elements());
3543 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003544 Object* writable_elems;
3545 { MaybeObject* maybe_writable_elems =
3546 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3547 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3548 return maybe_writable_elems;
3549 }
3550 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003551 set_elements(FixedArray::cast(writable_elems));
3552 Counters::cow_arrays_converted.Increment();
3553 return writable_elems;
3554}
3555
3556
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003557StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003558 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003559 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560}
3561
3562
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003563NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003564 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003565 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566}
3567
3568
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003569bool String::IsHashFieldComputed(uint32_t field) {
3570 return (field & kHashNotComputedMask) == 0;
3571}
3572
3573
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003574bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003575 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003576}
3577
3578
3579uint32_t String::Hash() {
3580 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003581 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003582 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003583 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003584 return ComputeAndSetHash();
3585}
3586
3587
ager@chromium.org7c537e22008-10-16 08:43:32 +00003588StringHasher::StringHasher(int length)
3589 : length_(length),
3590 raw_running_hash_(0),
3591 array_index_(0),
3592 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3593 is_first_char_(true),
3594 is_valid_(true) { }
3595
3596
3597bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003598 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003599}
3600
3601
3602void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003603 // Use the Jenkins one-at-a-time hash function to update the hash
3604 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003605 raw_running_hash_ += c;
3606 raw_running_hash_ += (raw_running_hash_ << 10);
3607 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003608 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003609 if (is_array_index_) {
3610 if (c < '0' || c > '9') {
3611 is_array_index_ = false;
3612 } else {
3613 int d = c - '0';
3614 if (is_first_char_) {
3615 is_first_char_ = false;
3616 if (c == '0' && length_ > 1) {
3617 is_array_index_ = false;
3618 return;
3619 }
3620 }
3621 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3622 is_array_index_ = false;
3623 } else {
3624 array_index_ = array_index_ * 10 + d;
3625 }
3626 }
3627 }
3628}
3629
3630
3631void StringHasher::AddCharacterNoIndex(uc32 c) {
3632 ASSERT(!is_array_index());
3633 raw_running_hash_ += c;
3634 raw_running_hash_ += (raw_running_hash_ << 10);
3635 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3636}
3637
3638
3639uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003640 // Get the calculated raw hash value and do some more bit ops to distribute
3641 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003642 uint32_t result = raw_running_hash_;
3643 result += (result << 3);
3644 result ^= (result >> 11);
3645 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003646 if (result == 0) {
3647 result = 27;
3648 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003649 return result;
3650}
3651
3652
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003653bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003654 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003655 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3656 return false;
3657 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003658 return SlowAsArrayIndex(index);
3659}
3660
3661
3662Object* JSObject::GetPrototype() {
3663 return JSObject::cast(this)->map()->prototype();
3664}
3665
3666
3667PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3668 return GetPropertyAttributeWithReceiver(this, key);
3669}
3670
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003671// TODO(504): this may be useful in other places too where JSGlobalProxy
3672// is used.
3673Object* JSObject::BypassGlobalProxy() {
3674 if (IsJSGlobalProxy()) {
3675 Object* proto = GetPrototype();
3676 if (proto->IsNull()) return Heap::undefined_value();
3677 ASSERT(proto->IsJSGlobalObject());
3678 return proto;
3679 }
3680 return this;
3681}
3682
3683
3684bool JSObject::HasHiddenPropertiesObject() {
3685 ASSERT(!IsJSGlobalProxy());
3686 return GetPropertyAttributePostInterceptor(this,
3687 Heap::hidden_symbol(),
3688 false) != ABSENT;
3689}
3690
3691
3692Object* JSObject::GetHiddenPropertiesObject() {
3693 ASSERT(!IsJSGlobalProxy());
3694 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003695 // You can't install a getter on a property indexed by the hidden symbol,
3696 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3697 // object.
3698 Object* result =
3699 GetLocalPropertyPostInterceptor(this,
3700 Heap::hidden_symbol(),
3701 &attributes)->ToObjectUnchecked();
3702 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003703}
3704
3705
lrn@chromium.org303ada72010-10-27 09:33:13 +00003706MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003707 ASSERT(!IsJSGlobalProxy());
3708 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3709 hidden_obj,
3710 DONT_ENUM);
3711}
3712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003713
3714bool JSObject::HasElement(uint32_t index) {
3715 return HasElementWithReceiver(this, index);
3716}
3717
3718
3719bool AccessorInfo::all_can_read() {
3720 return BooleanBit::get(flag(), kAllCanReadBit);
3721}
3722
3723
3724void AccessorInfo::set_all_can_read(bool value) {
3725 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3726}
3727
3728
3729bool AccessorInfo::all_can_write() {
3730 return BooleanBit::get(flag(), kAllCanWriteBit);
3731}
3732
3733
3734void AccessorInfo::set_all_can_write(bool value) {
3735 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3736}
3737
3738
ager@chromium.org870a0b62008-11-04 11:43:05 +00003739bool AccessorInfo::prohibits_overwriting() {
3740 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3741}
3742
3743
3744void AccessorInfo::set_prohibits_overwriting(bool value) {
3745 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3746}
3747
3748
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003749PropertyAttributes AccessorInfo::property_attributes() {
3750 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3751}
3752
3753
3754void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3755 ASSERT(AttributesField::is_valid(attributes));
3756 int rest_value = flag()->value() & ~AttributesField::mask();
3757 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3758}
3759
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003760template<typename Shape, typename Key>
3761void Dictionary<Shape, Key>::SetEntry(int entry,
3762 Object* key,
3763 Object* value,
3764 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003765 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003766 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003767 AssertNoAllocation no_gc;
3768 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003769 FixedArray::set(index, key, mode);
3770 FixedArray::set(index+1, value, mode);
3771 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003772}
3773
3774
3775void Map::ClearCodeCache() {
3776 // No write barrier is needed since empty_fixed_array is not in new space.
3777 // Please note this function is used during marking:
3778 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003779 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3780 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003781}
3782
3783
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003784void JSArray::EnsureSize(int required_size) {
3785 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003786 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003787 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3788 if (elts->length() < required_size) {
3789 // Doubling in size would be overkill, but leave some slack to avoid
3790 // constantly growing.
3791 Expand(required_size + (required_size >> 3));
3792 // It's a performance benefit to keep a frequently used array in new-space.
3793 } else if (!Heap::new_space()->Contains(elts) &&
3794 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3795 // Expand will allocate a new backing store in new space even if the size
3796 // we asked for isn't larger than what we had before.
3797 Expand(required_size);
3798 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003799}
3800
3801
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003802void JSArray::set_length(Smi* length) {
3803 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3804}
3805
3806
ager@chromium.org7c537e22008-10-16 08:43:32 +00003807void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003808 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003809 set_elements(storage);
3810}
3811
3812
lrn@chromium.org303ada72010-10-27 09:33:13 +00003813MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003814 if (length() == 0) return this;
3815 return Heap::CopyFixedArray(this);
3816}
3817
3818
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003819int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3820 return map->instance_size();
3821}
3822
3823
3824void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3825 v->VisitExternalReference(
3826 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3827}
3828
3829
3830template<typename StaticVisitor>
3831void Proxy::ProxyIterateBody() {
3832 StaticVisitor::VisitExternalReference(
3833 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3834}
3835
3836
3837void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3838 typedef v8::String::ExternalAsciiStringResource Resource;
3839 v->VisitExternalAsciiString(
3840 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3841}
3842
3843
3844template<typename StaticVisitor>
3845void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3846 typedef v8::String::ExternalAsciiStringResource Resource;
3847 StaticVisitor::VisitExternalAsciiString(
3848 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3849}
3850
3851
3852void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3853 typedef v8::String::ExternalStringResource Resource;
3854 v->VisitExternalTwoByteString(
3855 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3856}
3857
3858
3859template<typename StaticVisitor>
3860void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3861 typedef v8::String::ExternalStringResource Resource;
3862 StaticVisitor::VisitExternalTwoByteString(
3863 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3864}
3865
3866#define SLOT_ADDR(obj, offset) \
3867 reinterpret_cast<Object**>((obj)->address() + offset)
3868
3869template<int start_offset, int end_offset, int size>
3870void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3871 HeapObject* obj,
3872 ObjectVisitor* v) {
3873 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3874}
3875
3876
3877template<int start_offset>
3878void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3879 int object_size,
3880 ObjectVisitor* v) {
3881 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3882}
3883
3884#undef SLOT_ADDR
3885
3886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887#undef CAST_ACCESSOR
3888#undef INT_ACCESSORS
3889#undef SMI_ACCESSORS
3890#undef ACCESSORS
3891#undef FIELD_ADDR
3892#undef READ_FIELD
3893#undef WRITE_FIELD
3894#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003895#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896#undef READ_MEMADDR_FIELD
3897#undef WRITE_MEMADDR_FIELD
3898#undef READ_DOUBLE_FIELD
3899#undef WRITE_DOUBLE_FIELD
3900#undef READ_INT_FIELD
3901#undef WRITE_INT_FIELD
3902#undef READ_SHORT_FIELD
3903#undef WRITE_SHORT_FIELD
3904#undef READ_BYTE_FIELD
3905#undef WRITE_BYTE_FIELD
3906
3907
3908} } // namespace v8::internal
3909
3910#endif // V8_OBJECTS_INL_H_