blob: 3b83dd4869475bc4449332c695f05b48a54e8bc1 [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
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002513unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002514 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002515 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516}
2517
2518
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002519void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520 ASSERT(kind() == OPTIMIZED_FUNCTION);
2521 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002522 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523}
2524
2525
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002526unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002527 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002528 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529}
2530
2531
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002532void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533 ASSERT(kind() == FUNCTION);
2534 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002535 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536}
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
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002996bool SharedFunctionInfo::strict_mode() {
2997 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
2998}
2999
3000
3001void SharedFunctionInfo::set_strict_mode(bool value) {
3002 set_compiler_hints(BooleanBit::set(compiler_hints(),
3003 kStrictModeFunction,
3004 value));
3005}
3006
3007
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003008ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3009ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3010
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003011bool Script::HasValidSource() {
3012 Object* src = this->source();
3013 if (!src->IsString()) return true;
3014 String* src_str = String::cast(src);
3015 if (!StringShape(src_str).IsExternal()) return true;
3016 if (src_str->IsAsciiRepresentation()) {
3017 return ExternalAsciiString::cast(src)->resource() != NULL;
3018 } else if (src_str->IsTwoByteRepresentation()) {
3019 return ExternalTwoByteString::cast(src)->resource() != NULL;
3020 }
3021 return true;
3022}
3023
3024
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003025void SharedFunctionInfo::DontAdaptArguments() {
3026 ASSERT(code()->kind() == Code::BUILTIN);
3027 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3028}
3029
3030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003031int SharedFunctionInfo::start_position() {
3032 return start_position_and_type() >> kStartPositionShift;
3033}
3034
3035
3036void SharedFunctionInfo::set_start_position(int start_position) {
3037 set_start_position_and_type((start_position << kStartPositionShift)
3038 | (start_position_and_type() & ~kStartPositionMask));
3039}
3040
3041
3042Code* SharedFunctionInfo::code() {
3043 return Code::cast(READ_FIELD(this, kCodeOffset));
3044}
3045
3046
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003047Code* SharedFunctionInfo::unchecked_code() {
3048 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3049}
3050
3051
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003052void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003054 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003055}
3056
3057
ager@chromium.orgb5737492010-07-15 09:29:43 +00003058SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3059 return reinterpret_cast<SerializedScopeInfo*>(
3060 READ_FIELD(this, kScopeInfoOffset));
3061}
3062
3063
3064void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3065 WriteBarrierMode mode) {
3066 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3067 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3068}
3069
3070
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071Smi* SharedFunctionInfo::deopt_counter() {
3072 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3073}
3074
3075
3076void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3077 WRITE_FIELD(this, kDeoptCounterOffset, value);
3078}
3079
3080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003082 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003083}
3084
3085
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003086bool SharedFunctionInfo::IsApiFunction() {
3087 return function_data()->IsFunctionTemplateInfo();
3088}
3089
3090
3091FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3092 ASSERT(IsApiFunction());
3093 return FunctionTemplateInfo::cast(function_data());
3094}
3095
3096
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003097bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003098 return function_data()->IsSmi();
3099}
3100
3101
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003102BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3103 ASSERT(HasBuiltinFunctionId());
3104 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003105}
3106
3107
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003108int SharedFunctionInfo::code_age() {
3109 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3110}
3111
3112
3113void SharedFunctionInfo::set_code_age(int code_age) {
3114 set_compiler_hints(compiler_hints() |
3115 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3116}
3117
3118
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003119bool SharedFunctionInfo::has_deoptimization_support() {
3120 Code* code = this->code();
3121 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3122}
3123
3124
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003125bool JSFunction::IsBuiltin() {
3126 return context()->global()->IsJSBuiltinsObject();
3127}
3128
3129
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130bool JSFunction::NeedsArgumentsAdaption() {
3131 return shared()->formal_parameter_count() !=
3132 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3133}
3134
3135
3136bool JSFunction::IsOptimized() {
3137 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3138}
3139
3140
3141bool JSFunction::IsMarkedForLazyRecompilation() {
3142 return code() == Builtins::builtin(Builtins::LazyRecompile);
3143}
3144
3145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003146Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003147 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003148}
3149
3150
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003151Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003152 return reinterpret_cast<Code*>(
3153 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003154}
3155
3156
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003157void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003158 // Skip the write barrier because code is never in new space.
3159 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003160 Address entry = value->entry();
3161 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003162}
3163
3164
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165void JSFunction::ReplaceCode(Code* code) {
3166 bool was_optimized = IsOptimized();
3167 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3168
3169 set_code(code);
3170
3171 // Add/remove the function from the list of optimized functions for this
3172 // context based on the state change.
3173 if (!was_optimized && is_optimized) {
3174 context()->global_context()->AddOptimizedFunction(this);
3175 }
3176 if (was_optimized && !is_optimized) {
3177 context()->global_context()->RemoveOptimizedFunction(this);
3178 }
3179}
3180
3181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003182Context* JSFunction::context() {
3183 return Context::cast(READ_FIELD(this, kContextOffset));
3184}
3185
3186
3187Object* JSFunction::unchecked_context() {
3188 return READ_FIELD(this, kContextOffset);
3189}
3190
3191
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003192SharedFunctionInfo* JSFunction::unchecked_shared() {
3193 return reinterpret_cast<SharedFunctionInfo*>(
3194 READ_FIELD(this, kSharedFunctionInfoOffset));
3195}
3196
3197
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003198void JSFunction::set_context(Object* value) {
3199 ASSERT(value == Heap::undefined_value() || value->IsContext());
3200 WRITE_FIELD(this, kContextOffset, value);
3201 WRITE_BARRIER(this, kContextOffset);
3202}
3203
3204ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3205 kPrototypeOrInitialMapOffset)
3206
3207
3208Map* JSFunction::initial_map() {
3209 return Map::cast(prototype_or_initial_map());
3210}
3211
3212
3213void JSFunction::set_initial_map(Map* value) {
3214 set_prototype_or_initial_map(value);
3215}
3216
3217
3218bool JSFunction::has_initial_map() {
3219 return prototype_or_initial_map()->IsMap();
3220}
3221
3222
3223bool JSFunction::has_instance_prototype() {
3224 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3225}
3226
3227
3228bool JSFunction::has_prototype() {
3229 return map()->has_non_instance_prototype() || has_instance_prototype();
3230}
3231
3232
3233Object* JSFunction::instance_prototype() {
3234 ASSERT(has_instance_prototype());
3235 if (has_initial_map()) return initial_map()->prototype();
3236 // When there is no initial map and the prototype is a JSObject, the
3237 // initial map field is used for the prototype field.
3238 return prototype_or_initial_map();
3239}
3240
3241
3242Object* JSFunction::prototype() {
3243 ASSERT(has_prototype());
3244 // If the function's prototype property has been set to a non-JSObject
3245 // value, that value is stored in the constructor field of the map.
3246 if (map()->has_non_instance_prototype()) return map()->constructor();
3247 return instance_prototype();
3248}
3249
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003250bool JSFunction::should_have_prototype() {
3251 return map()->function_with_prototype();
3252}
3253
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254
3255bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003256 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257}
3258
3259
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003260int JSFunction::NumberOfLiterals() {
3261 return literals()->length();
3262}
3263
3264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003266 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003267 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003268}
3269
3270
3271void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3272 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003273 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003274 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3275 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3276}
3277
3278
3279Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003280 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003281 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3282}
3283
3284
3285void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3286 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003287 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003288 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3289 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003290}
3291
3292
3293Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003294 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003295}
3296
3297
3298void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003299 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300}
3301
3302
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003303ACCESSORS(JSValue, value, Object, kValueOffset)
3304
3305
3306JSValue* JSValue::cast(Object* obj) {
3307 ASSERT(obj->IsJSValue());
3308 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3309 return reinterpret_cast<JSValue*>(obj);
3310}
3311
3312
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003313ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3314ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3315ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3316ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3317ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3318SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3319SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3320
3321
3322JSMessageObject* JSMessageObject::cast(Object* obj) {
3323 ASSERT(obj->IsJSMessageObject());
3324 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3325 return reinterpret_cast<JSMessageObject*>(obj);
3326}
3327
3328
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003330ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003331ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003332
3333
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003334byte* Code::instruction_start() {
3335 return FIELD_ADDR(this, kHeaderSize);
3336}
3337
3338
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003339byte* Code::instruction_end() {
3340 return instruction_start() + instruction_size();
3341}
3342
3343
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003344int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003345 return RoundUp(instruction_size(), kObjectAlignment);
3346}
3347
3348
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003349FixedArray* Code::unchecked_deoptimization_data() {
3350 return reinterpret_cast<FixedArray*>(
3351 READ_FIELD(this, kDeoptimizationDataOffset));
3352}
3353
3354
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003355ByteArray* Code::unchecked_relocation_info() {
3356 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357}
3358
3359
3360byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003361 return unchecked_relocation_info()->GetDataStartAddress();
3362}
3363
3364
3365int Code::relocation_size() {
3366 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367}
3368
3369
3370byte* Code::entry() {
3371 return instruction_start();
3372}
3373
3374
3375bool Code::contains(byte* pc) {
3376 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003377 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003378}
3379
3380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381ACCESSORS(JSArray, length, Object, kLengthOffset)
3382
3383
ager@chromium.org236ad962008-09-25 09:45:57 +00003384ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003385
3386
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003387JSRegExp::Type JSRegExp::TypeTag() {
3388 Object* data = this->data();
3389 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3390 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3391 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003392}
3393
3394
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003395int JSRegExp::CaptureCount() {
3396 switch (TypeTag()) {
3397 case ATOM:
3398 return 0;
3399 case IRREGEXP:
3400 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3401 default:
3402 UNREACHABLE();
3403 return -1;
3404 }
3405}
3406
3407
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003408JSRegExp::Flags JSRegExp::GetFlags() {
3409 ASSERT(this->data()->IsFixedArray());
3410 Object* data = this->data();
3411 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3412 return Flags(smi->value());
3413}
3414
3415
3416String* JSRegExp::Pattern() {
3417 ASSERT(this->data()->IsFixedArray());
3418 Object* data = this->data();
3419 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3420 return pattern;
3421}
3422
3423
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003424Object* JSRegExp::DataAt(int index) {
3425 ASSERT(TypeTag() != NOT_COMPILED);
3426 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003427}
3428
3429
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003430void JSRegExp::SetDataAt(int index, Object* value) {
3431 ASSERT(TypeTag() != NOT_COMPILED);
3432 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3433 FixedArray::cast(data())->set(index, value);
3434}
3435
3436
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003437JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003438 if (map()->has_fast_elements()) {
3439 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3440 elements()->map() == Heap::fixed_cow_array_map());
3441 return FAST_ELEMENTS;
3442 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003443 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003444 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003445 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3446 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003447 ASSERT(array->IsDictionary());
3448 return DICTIONARY_ELEMENTS;
3449 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003450 if (array->IsExternalArray()) {
3451 switch (array->map()->instance_type()) {
3452 case EXTERNAL_BYTE_ARRAY_TYPE:
3453 return EXTERNAL_BYTE_ELEMENTS;
3454 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3455 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3456 case EXTERNAL_SHORT_ARRAY_TYPE:
3457 return EXTERNAL_SHORT_ELEMENTS;
3458 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3459 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3460 case EXTERNAL_INT_ARRAY_TYPE:
3461 return EXTERNAL_INT_ELEMENTS;
3462 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3463 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3464 default:
3465 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3466 return EXTERNAL_FLOAT_ELEMENTS;
3467 }
3468 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003469 ASSERT(array->IsPixelArray());
3470 return PIXEL_ELEMENTS;
3471}
3472
3473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003475 return GetElementsKind() == FAST_ELEMENTS;
3476}
3477
3478
3479bool JSObject::HasDictionaryElements() {
3480 return GetElementsKind() == DICTIONARY_ELEMENTS;
3481}
3482
3483
3484bool JSObject::HasPixelElements() {
3485 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486}
3487
3488
ager@chromium.org3811b432009-10-28 14:53:37 +00003489bool JSObject::HasExternalArrayElements() {
3490 return (HasExternalByteElements() ||
3491 HasExternalUnsignedByteElements() ||
3492 HasExternalShortElements() ||
3493 HasExternalUnsignedShortElements() ||
3494 HasExternalIntElements() ||
3495 HasExternalUnsignedIntElements() ||
3496 HasExternalFloatElements());
3497}
3498
3499
3500bool JSObject::HasExternalByteElements() {
3501 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3502}
3503
3504
3505bool JSObject::HasExternalUnsignedByteElements() {
3506 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3507}
3508
3509
3510bool JSObject::HasExternalShortElements() {
3511 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3512}
3513
3514
3515bool JSObject::HasExternalUnsignedShortElements() {
3516 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3517}
3518
3519
3520bool JSObject::HasExternalIntElements() {
3521 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3522}
3523
3524
3525bool JSObject::HasExternalUnsignedIntElements() {
3526 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3527}
3528
3529
3530bool JSObject::HasExternalFloatElements() {
3531 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3532}
3533
3534
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003535bool JSObject::HasNamedInterceptor() {
3536 return map()->has_named_interceptor();
3537}
3538
3539
3540bool JSObject::HasIndexedInterceptor() {
3541 return map()->has_indexed_interceptor();
3542}
3543
3544
ager@chromium.org5c838252010-02-19 08:53:10 +00003545bool JSObject::AllowsSetElementsLength() {
3546 bool result = elements()->IsFixedArray();
3547 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3548 return result;
3549}
3550
3551
lrn@chromium.org303ada72010-10-27 09:33:13 +00003552MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003553 ASSERT(HasFastElements());
3554 FixedArray* elems = FixedArray::cast(elements());
3555 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003556 Object* writable_elems;
3557 { MaybeObject* maybe_writable_elems =
3558 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3559 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3560 return maybe_writable_elems;
3561 }
3562 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003563 set_elements(FixedArray::cast(writable_elems));
3564 Counters::cow_arrays_converted.Increment();
3565 return writable_elems;
3566}
3567
3568
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003569StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003570 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003571 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003572}
3573
3574
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003575NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003576 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003577 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578}
3579
3580
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003581bool String::IsHashFieldComputed(uint32_t field) {
3582 return (field & kHashNotComputedMask) == 0;
3583}
3584
3585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003586bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003587 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003588}
3589
3590
3591uint32_t String::Hash() {
3592 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003593 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003594 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003595 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003596 return ComputeAndSetHash();
3597}
3598
3599
ager@chromium.org7c537e22008-10-16 08:43:32 +00003600StringHasher::StringHasher(int length)
3601 : length_(length),
3602 raw_running_hash_(0),
3603 array_index_(0),
3604 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3605 is_first_char_(true),
3606 is_valid_(true) { }
3607
3608
3609bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003610 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003611}
3612
3613
3614void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003615 // Use the Jenkins one-at-a-time hash function to update the hash
3616 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003617 raw_running_hash_ += c;
3618 raw_running_hash_ += (raw_running_hash_ << 10);
3619 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003620 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003621 if (is_array_index_) {
3622 if (c < '0' || c > '9') {
3623 is_array_index_ = false;
3624 } else {
3625 int d = c - '0';
3626 if (is_first_char_) {
3627 is_first_char_ = false;
3628 if (c == '0' && length_ > 1) {
3629 is_array_index_ = false;
3630 return;
3631 }
3632 }
3633 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3634 is_array_index_ = false;
3635 } else {
3636 array_index_ = array_index_ * 10 + d;
3637 }
3638 }
3639 }
3640}
3641
3642
3643void StringHasher::AddCharacterNoIndex(uc32 c) {
3644 ASSERT(!is_array_index());
3645 raw_running_hash_ += c;
3646 raw_running_hash_ += (raw_running_hash_ << 10);
3647 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3648}
3649
3650
3651uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003652 // Get the calculated raw hash value and do some more bit ops to distribute
3653 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003654 uint32_t result = raw_running_hash_;
3655 result += (result << 3);
3656 result ^= (result >> 11);
3657 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003658 if (result == 0) {
3659 result = 27;
3660 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003661 return result;
3662}
3663
3664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003665bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003666 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003667 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3668 return false;
3669 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003670 return SlowAsArrayIndex(index);
3671}
3672
3673
3674Object* JSObject::GetPrototype() {
3675 return JSObject::cast(this)->map()->prototype();
3676}
3677
3678
3679PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3680 return GetPropertyAttributeWithReceiver(this, key);
3681}
3682
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003683// TODO(504): this may be useful in other places too where JSGlobalProxy
3684// is used.
3685Object* JSObject::BypassGlobalProxy() {
3686 if (IsJSGlobalProxy()) {
3687 Object* proto = GetPrototype();
3688 if (proto->IsNull()) return Heap::undefined_value();
3689 ASSERT(proto->IsJSGlobalObject());
3690 return proto;
3691 }
3692 return this;
3693}
3694
3695
3696bool JSObject::HasHiddenPropertiesObject() {
3697 ASSERT(!IsJSGlobalProxy());
3698 return GetPropertyAttributePostInterceptor(this,
3699 Heap::hidden_symbol(),
3700 false) != ABSENT;
3701}
3702
3703
3704Object* JSObject::GetHiddenPropertiesObject() {
3705 ASSERT(!IsJSGlobalProxy());
3706 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003707 // You can't install a getter on a property indexed by the hidden symbol,
3708 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3709 // object.
3710 Object* result =
3711 GetLocalPropertyPostInterceptor(this,
3712 Heap::hidden_symbol(),
3713 &attributes)->ToObjectUnchecked();
3714 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003715}
3716
3717
lrn@chromium.org303ada72010-10-27 09:33:13 +00003718MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003719 ASSERT(!IsJSGlobalProxy());
3720 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3721 hidden_obj,
3722 DONT_ENUM);
3723}
3724
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003725
3726bool JSObject::HasElement(uint32_t index) {
3727 return HasElementWithReceiver(this, index);
3728}
3729
3730
3731bool AccessorInfo::all_can_read() {
3732 return BooleanBit::get(flag(), kAllCanReadBit);
3733}
3734
3735
3736void AccessorInfo::set_all_can_read(bool value) {
3737 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3738}
3739
3740
3741bool AccessorInfo::all_can_write() {
3742 return BooleanBit::get(flag(), kAllCanWriteBit);
3743}
3744
3745
3746void AccessorInfo::set_all_can_write(bool value) {
3747 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3748}
3749
3750
ager@chromium.org870a0b62008-11-04 11:43:05 +00003751bool AccessorInfo::prohibits_overwriting() {
3752 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3753}
3754
3755
3756void AccessorInfo::set_prohibits_overwriting(bool value) {
3757 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3758}
3759
3760
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003761PropertyAttributes AccessorInfo::property_attributes() {
3762 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3763}
3764
3765
3766void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3767 ASSERT(AttributesField::is_valid(attributes));
3768 int rest_value = flag()->value() & ~AttributesField::mask();
3769 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3770}
3771
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003772template<typename Shape, typename Key>
3773void Dictionary<Shape, Key>::SetEntry(int entry,
3774 Object* key,
3775 Object* value,
3776 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003777 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003778 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003779 AssertNoAllocation no_gc;
3780 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003781 FixedArray::set(index, key, mode);
3782 FixedArray::set(index+1, value, mode);
3783 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784}
3785
3786
3787void Map::ClearCodeCache() {
3788 // No write barrier is needed since empty_fixed_array is not in new space.
3789 // Please note this function is used during marking:
3790 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003791 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3792 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003793}
3794
3795
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003796void JSArray::EnsureSize(int required_size) {
3797 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003798 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003799 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3800 if (elts->length() < required_size) {
3801 // Doubling in size would be overkill, but leave some slack to avoid
3802 // constantly growing.
3803 Expand(required_size + (required_size >> 3));
3804 // It's a performance benefit to keep a frequently used array in new-space.
3805 } else if (!Heap::new_space()->Contains(elts) &&
3806 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3807 // Expand will allocate a new backing store in new space even if the size
3808 // we asked for isn't larger than what we had before.
3809 Expand(required_size);
3810 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003811}
3812
3813
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003814void JSArray::set_length(Smi* length) {
3815 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3816}
3817
3818
ager@chromium.org7c537e22008-10-16 08:43:32 +00003819void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003820 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003821 set_elements(storage);
3822}
3823
3824
lrn@chromium.org303ada72010-10-27 09:33:13 +00003825MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003826 if (length() == 0) return this;
3827 return Heap::CopyFixedArray(this);
3828}
3829
3830
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003831int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3832 return map->instance_size();
3833}
3834
3835
3836void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3837 v->VisitExternalReference(
3838 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3839}
3840
3841
3842template<typename StaticVisitor>
3843void Proxy::ProxyIterateBody() {
3844 StaticVisitor::VisitExternalReference(
3845 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3846}
3847
3848
3849void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3850 typedef v8::String::ExternalAsciiStringResource Resource;
3851 v->VisitExternalAsciiString(
3852 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3853}
3854
3855
3856template<typename StaticVisitor>
3857void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3858 typedef v8::String::ExternalAsciiStringResource Resource;
3859 StaticVisitor::VisitExternalAsciiString(
3860 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3861}
3862
3863
3864void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3865 typedef v8::String::ExternalStringResource Resource;
3866 v->VisitExternalTwoByteString(
3867 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3868}
3869
3870
3871template<typename StaticVisitor>
3872void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3873 typedef v8::String::ExternalStringResource Resource;
3874 StaticVisitor::VisitExternalTwoByteString(
3875 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3876}
3877
3878#define SLOT_ADDR(obj, offset) \
3879 reinterpret_cast<Object**>((obj)->address() + offset)
3880
3881template<int start_offset, int end_offset, int size>
3882void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3883 HeapObject* obj,
3884 ObjectVisitor* v) {
3885 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3886}
3887
3888
3889template<int start_offset>
3890void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3891 int object_size,
3892 ObjectVisitor* v) {
3893 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3894}
3895
3896#undef SLOT_ADDR
3897
3898
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003899#undef CAST_ACCESSOR
3900#undef INT_ACCESSORS
3901#undef SMI_ACCESSORS
3902#undef ACCESSORS
3903#undef FIELD_ADDR
3904#undef READ_FIELD
3905#undef WRITE_FIELD
3906#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003907#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003908#undef READ_MEMADDR_FIELD
3909#undef WRITE_MEMADDR_FIELD
3910#undef READ_DOUBLE_FIELD
3911#undef WRITE_DOUBLE_FIELD
3912#undef READ_INT_FIELD
3913#undef WRITE_INT_FIELD
3914#undef READ_SHORT_FIELD
3915#undef WRITE_SHORT_FIELD
3916#undef READ_BYTE_FIELD
3917#undef WRITE_BYTE_FIELD
3918
3919
3920} } // namespace v8::internal
3921
3922#endif // V8_OBJECTS_INL_H_