blob: 70ed47be1f4edb17dd08033249d13b00ea273a44 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000046#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000047
kasperl@chromium.org71affb52009-05-26 05:44:31 +000048namespace v8 {
49namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050
51PropertyDetails::PropertyDetails(Smi* smi) {
52 value_ = smi->value();
53}
54
55
56Smi* PropertyDetails::AsSmi() {
57 return Smi::FromInt(value_);
58}
59
60
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000061PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000062 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000063 return PropertyDetails(smi);
64}
65
66
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000067#define CAST_ACCESSOR(type) \
68 type* type::cast(Object* object) { \
69 ASSERT(object->Is##type()); \
70 return reinterpret_cast<type*>(object); \
71 }
72
73
74#define INT_ACCESSORS(holder, name, offset) \
75 int holder::name() { return READ_INT_FIELD(this, offset); } \
76 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
77
78
79#define ACCESSORS(holder, name, type, offset) \
80 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000081 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000082 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000083 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
84 }
85
86
87// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
88#define ACCESSORS_GCSAFE(holder, name, type, offset) \
89 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
90 void holder::set_##name(type* value, WriteBarrierMode mode) { \
91 WRITE_FIELD(this, offset, value); \
92 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 }
94
95
96#define SMI_ACCESSORS(holder, name, offset) \
97 int holder::name() { \
98 Object* value = READ_FIELD(this, offset); \
99 return Smi::cast(value)->value(); \
100 } \
101 void holder::set_##name(int value) { \
102 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
103 }
104
105
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000106#define BOOL_GETTER(holder, field, name, offset) \
107 bool holder::name() { \
108 return BooleanBit::get(field(), offset); \
109 } \
110
111
112#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113 bool holder::name() { \
114 return BooleanBit::get(field(), offset); \
115 } \
116 void holder::set_##name(bool value) { \
117 set_##field(BooleanBit::set(field(), offset, value)); \
118 }
119
120
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000121bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
122 // There is a constraint on the object; check.
123 if (!this->IsJSObject()) return false;
124 // Fetch the constructor function of the object.
125 Object* cons_obj = JSObject::cast(this)->map()->constructor();
126 if (!cons_obj->IsJSFunction()) return false;
127 JSFunction* fun = JSFunction::cast(cons_obj);
128 // Iterate through the chain of inheriting function templates to
129 // see if the required one occurs.
130 for (Object* type = fun->shared()->function_data();
131 type->IsFunctionTemplateInfo();
132 type = FunctionTemplateInfo::cast(type)->parent_template()) {
133 if (type == expected) return true;
134 }
135 // Didn't find the required type in the inheritance chain.
136 return false;
137}
138
139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140bool Object::IsSmi() {
141 return HAS_SMI_TAG(this);
142}
143
144
145bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000146 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000147}
148
149
150bool Object::IsHeapNumber() {
151 return Object::IsHeapObject()
152 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
153}
154
155
156bool Object::IsString() {
157 return Object::IsHeapObject()
158 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
159}
160
161
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000162bool Object::IsSpecObject() {
163 return Object::IsHeapObject()
164 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
165}
166
167
ager@chromium.org870a0b62008-11-04 11:43:05 +0000168bool Object::IsSymbol() {
169 if (!this->IsHeapObject()) return false;
170 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000171 // Because the symbol tag is non-zero and no non-string types have the
172 // symbol bit set we can test for symbols with a very simple test
173 // operation.
174 ASSERT(kSymbolTag != 0);
175 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
176 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000177}
178
179
180bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181 if (!this->IsHeapObject()) return false;
182 uint32_t type = HeapObject::cast(this)->map()->instance_type();
183 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
184 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000185}
186
187
ager@chromium.org870a0b62008-11-04 11:43:05 +0000188bool Object::IsSeqString() {
189 if (!IsString()) return false;
190 return StringShape(String::cast(this)).IsSequential();
191}
192
193
194bool Object::IsSeqAsciiString() {
195 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000196 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000197 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000198}
199
200
201bool Object::IsSeqTwoByteString() {
202 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000203 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000204 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211}
212
213
214bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000215 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000216 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000217 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000218}
219
220
221bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000222 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000223 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000224 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225}
226
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000227bool Object::HasValidElements() {
228 // Dictionary is covered under FixedArray.
229 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
230}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231
ager@chromium.org870a0b62008-11-04 11:43:05 +0000232StringShape::StringShape(String* str)
233 : type_(str->map()->instance_type()) {
234 set_valid();
235 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236}
237
238
ager@chromium.org870a0b62008-11-04 11:43:05 +0000239StringShape::StringShape(Map* map)
240 : type_(map->instance_type()) {
241 set_valid();
242 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
ager@chromium.org870a0b62008-11-04 11:43:05 +0000246StringShape::StringShape(InstanceType t)
247 : type_(static_cast<uint32_t>(t)) {
248 set_valid();
249 ASSERT((type_ & kIsNotStringMask) == kStringTag);
250}
251
252
253bool StringShape::IsSymbol() {
254 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000255 ASSERT(kSymbolTag != 0);
256 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000257}
258
259
ager@chromium.org5ec48922009-05-05 07:25:34 +0000260bool String::IsAsciiRepresentation() {
261 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000262 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263}
264
265
ager@chromium.org5ec48922009-05-05 07:25:34 +0000266bool String::IsTwoByteRepresentation() {
267 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000268 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000269}
270
271
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000272bool String::HasOnlyAsciiChars() {
273 uint32_t type = map()->instance_type();
274 return (type & kStringEncodingMask) == kAsciiStringTag ||
275 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000276}
277
278
ager@chromium.org870a0b62008-11-04 11:43:05 +0000279bool StringShape::IsCons() {
280 return (type_ & kStringRepresentationMask) == kConsStringTag;
281}
282
283
ager@chromium.org870a0b62008-11-04 11:43:05 +0000284bool StringShape::IsExternal() {
285 return (type_ & kStringRepresentationMask) == kExternalStringTag;
286}
287
288
289bool StringShape::IsSequential() {
290 return (type_ & kStringRepresentationMask) == kSeqStringTag;
291}
292
293
294StringRepresentationTag StringShape::representation_tag() {
295 uint32_t tag = (type_ & kStringRepresentationMask);
296 return static_cast<StringRepresentationTag>(tag);
297}
298
299
300uint32_t StringShape::full_representation_tag() {
301 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
302}
303
304
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000305STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
306 Internals::kFullStringRepresentationMask);
307
308
ager@chromium.org870a0b62008-11-04 11:43:05 +0000309bool StringShape::IsSequentialAscii() {
310 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
311}
312
313
314bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000315 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000316}
317
318
319bool StringShape::IsExternalAscii() {
320 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
321}
322
323
324bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000325 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000326}
327
328
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000329STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
330 Internals::kExternalTwoByteRepresentationTag);
331
332
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000333uc32 FlatStringReader::Get(int index) {
334 ASSERT(0 <= index && index <= length_);
335 if (is_ascii_) {
336 return static_cast<const byte*>(start_)[index];
337 } else {
338 return static_cast<const uc16*>(start_)[index];
339 }
340}
341
342
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000343bool Object::IsNumber() {
344 return IsSmi() || IsHeapNumber();
345}
346
347
348bool Object::IsByteArray() {
349 return Object::IsHeapObject()
350 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
351}
352
353
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000354bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000355 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000356 HeapObject::cast(this)->map()->instance_type() ==
357 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000358}
359
360
ager@chromium.org3811b432009-10-28 14:53:37 +0000361bool Object::IsExternalArray() {
362 if (!Object::IsHeapObject())
363 return false;
364 InstanceType instance_type =
365 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000366 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
367 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000368}
369
370
371bool Object::IsExternalByteArray() {
372 return Object::IsHeapObject() &&
373 HeapObject::cast(this)->map()->instance_type() ==
374 EXTERNAL_BYTE_ARRAY_TYPE;
375}
376
377
378bool Object::IsExternalUnsignedByteArray() {
379 return Object::IsHeapObject() &&
380 HeapObject::cast(this)->map()->instance_type() ==
381 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
382}
383
384
385bool Object::IsExternalShortArray() {
386 return Object::IsHeapObject() &&
387 HeapObject::cast(this)->map()->instance_type() ==
388 EXTERNAL_SHORT_ARRAY_TYPE;
389}
390
391
392bool Object::IsExternalUnsignedShortArray() {
393 return Object::IsHeapObject() &&
394 HeapObject::cast(this)->map()->instance_type() ==
395 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
396}
397
398
399bool Object::IsExternalIntArray() {
400 return Object::IsHeapObject() &&
401 HeapObject::cast(this)->map()->instance_type() ==
402 EXTERNAL_INT_ARRAY_TYPE;
403}
404
405
406bool Object::IsExternalUnsignedIntArray() {
407 return Object::IsHeapObject() &&
408 HeapObject::cast(this)->map()->instance_type() ==
409 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
410}
411
412
413bool Object::IsExternalFloatArray() {
414 return Object::IsHeapObject() &&
415 HeapObject::cast(this)->map()->instance_type() ==
416 EXTERNAL_FLOAT_ARRAY_TYPE;
417}
418
419
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000420bool Object::IsExternalDoubleArray() {
421 return Object::IsHeapObject() &&
422 HeapObject::cast(this)->map()->instance_type() ==
423 EXTERNAL_DOUBLE_ARRAY_TYPE;
424}
425
426
lrn@chromium.org303ada72010-10-27 09:33:13 +0000427bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000428 return HAS_FAILURE_TAG(this);
429}
430
431
lrn@chromium.org303ada72010-10-27 09:33:13 +0000432bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433 return HAS_FAILURE_TAG(this)
434 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
435}
436
437
lrn@chromium.org303ada72010-10-27 09:33:13 +0000438bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000439 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000440 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000441}
442
443
lrn@chromium.org303ada72010-10-27 09:33:13 +0000444bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445 return this == Failure::Exception();
446}
447
448
lrn@chromium.org303ada72010-10-27 09:33:13 +0000449bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000450 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000451}
452
453
454Failure* Failure::cast(MaybeObject* obj) {
455 ASSERT(HAS_FAILURE_TAG(obj));
456 return reinterpret_cast<Failure*>(obj);
457}
458
459
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000460bool Object::IsJSReceiver() {
461 return IsHeapObject() &&
462 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
463}
464
465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000466bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000467 return IsJSReceiver() && !IsJSProxy();
468}
469
470
471bool Object::IsJSProxy() {
472 return Object::IsHeapObject() &&
473 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
474 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
475}
476
477
478bool Object::IsJSFunctionProxy() {
479 return Object::IsHeapObject() &&
480 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000481}
482
483
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000484bool Object::IsJSWeakMap() {
485 return Object::IsJSObject() &&
486 HeapObject::cast(this)->map()->instance_type() == JS_WEAK_MAP_TYPE;
487}
488
489
ager@chromium.org32912102009-01-16 10:38:43 +0000490bool Object::IsJSContextExtensionObject() {
491 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000492 && (HeapObject::cast(this)->map()->instance_type() ==
493 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000494}
495
496
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000497bool Object::IsMap() {
498 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000499 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500}
501
502
503bool Object::IsFixedArray() {
504 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000505 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000506}
507
508
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000509bool Object::IsFixedDoubleArray() {
510 return Object::IsHeapObject()
511 && HeapObject::cast(this)->map()->instance_type() ==
512 FIXED_DOUBLE_ARRAY_TYPE;
513}
514
515
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516bool Object::IsDescriptorArray() {
517 return IsFixedArray();
518}
519
520
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000521bool Object::IsDeoptimizationInputData() {
522 // Must be a fixed array.
523 if (!IsFixedArray()) return false;
524
525 // There's no sure way to detect the difference between a fixed array and
526 // a deoptimization data array. Since this is used for asserts we can
527 // check that the length is zero or else the fixed size plus a multiple of
528 // the entry size.
529 int length = FixedArray::cast(this)->length();
530 if (length == 0) return true;
531
532 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
533 return length >= 0 &&
534 length % DeoptimizationInputData::kDeoptEntrySize == 0;
535}
536
537
538bool Object::IsDeoptimizationOutputData() {
539 if (!IsFixedArray()) return false;
540 // There's actually no way to see the difference between a fixed array and
541 // a deoptimization data array. Since this is used for asserts we can check
542 // that the length is plausible though.
543 if (FixedArray::cast(this)->length() % 2 != 0) return false;
544 return true;
545}
546
547
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000548bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000550 Map* map = HeapObject::cast(this)->map();
551 Heap* heap = map->GetHeap();
552 return (map == heap->function_context_map() ||
553 map == heap->catch_context_map() ||
554 map == heap->with_context_map() ||
555 map == heap->global_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000556 }
557 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558}
559
560
561bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000562 return Object::IsHeapObject() &&
563 HeapObject::cast(this)->map() ==
564 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000565}
566
567
568bool Object::IsJSFunction() {
569 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000570 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571}
572
573
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000574template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575 return obj->IsJSFunction();
576}
577
578
579bool Object::IsCode() {
580 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000581 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000582}
583
584
585bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587 return Object::IsHeapObject()
588 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
589}
590
591
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000592bool Object::IsJSGlobalPropertyCell() {
593 return Object::IsHeapObject()
594 && HeapObject::cast(this)->map()->instance_type()
595 == JS_GLOBAL_PROPERTY_CELL_TYPE;
596}
597
598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599bool Object::IsSharedFunctionInfo() {
600 return Object::IsHeapObject() &&
601 (HeapObject::cast(this)->map()->instance_type() ==
602 SHARED_FUNCTION_INFO_TYPE);
603}
604
605
606bool Object::IsJSValue() {
607 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000608 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
609}
610
611
612bool Object::IsJSMessageObject() {
613 return Object::IsHeapObject()
614 && (HeapObject::cast(this)->map()->instance_type() ==
615 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616}
617
618
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000619bool Object::IsStringWrapper() {
620 return IsJSValue() && JSValue::cast(this)->value()->IsString();
621}
622
623
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000624bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000625 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000626 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627}
628
629
630bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000631 return IsOddball() &&
632 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633}
634
635
636bool Object::IsJSArray() {
637 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000638 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000639}
640
641
ager@chromium.org236ad962008-09-25 09:45:57 +0000642bool Object::IsJSRegExp() {
643 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000644 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000645}
646
647
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000648template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649 return obj->IsJSArray();
650}
651
652
653bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 return Object::IsHeapObject() &&
655 HeapObject::cast(this)->map() ==
656 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
660bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000661 return IsHashTable() &&
662 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
666bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000667 return IsHashTable() && this ==
668 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669}
670
671
ager@chromium.orgac091b72010-05-05 07:34:42 +0000672bool Object::IsJSFunctionResultCache() {
673 if (!IsFixedArray()) return false;
674 FixedArray* self = FixedArray::cast(this);
675 int length = self->length();
676 if (length < JSFunctionResultCache::kEntriesIndex) return false;
677 if ((length - JSFunctionResultCache::kEntriesIndex)
678 % JSFunctionResultCache::kEntrySize != 0) {
679 return false;
680 }
681#ifdef DEBUG
682 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
683#endif
684 return true;
685}
686
687
ricow@chromium.org65fae842010-08-25 15:26:24 +0000688bool Object::IsNormalizedMapCache() {
689 if (!IsFixedArray()) return false;
690 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
691 return false;
692 }
693#ifdef DEBUG
694 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
695#endif
696 return true;
697}
698
699
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000700bool Object::IsCompilationCacheTable() {
701 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000702}
703
704
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000705bool Object::IsCodeCacheHashTable() {
706 return IsHashTable();
707}
708
709
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000710bool Object::IsPolymorphicCodeCacheHashTable() {
711 return IsHashTable();
712}
713
714
ager@chromium.org236ad962008-09-25 09:45:57 +0000715bool Object::IsMapCache() {
716 return IsHashTable();
717}
718
719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720bool Object::IsPrimitive() {
721 return IsOddball() || IsNumber() || IsString();
722}
723
724
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000725bool Object::IsJSGlobalProxy() {
726 bool result = IsHeapObject() &&
727 (HeapObject::cast(this)->map()->instance_type() ==
728 JS_GLOBAL_PROXY_TYPE);
729 ASSERT(!result || IsAccessCheckNeeded());
730 return result;
731}
732
733
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000734bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000735 if (!IsHeapObject()) return false;
736
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000737 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738 return type == JS_GLOBAL_OBJECT_TYPE ||
739 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000740}
741
742
743bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000744 return IsHeapObject() &&
745 (HeapObject::cast(this)->map()->instance_type() ==
746 JS_GLOBAL_OBJECT_TYPE);
747}
748
749
750bool Object::IsJSBuiltinsObject() {
751 return IsHeapObject() &&
752 (HeapObject::cast(this)->map()->instance_type() ==
753 JS_BUILTINS_OBJECT_TYPE);
754}
755
756
757bool Object::IsUndetectableObject() {
758 return IsHeapObject()
759 && HeapObject::cast(this)->map()->is_undetectable();
760}
761
762
763bool Object::IsAccessCheckNeeded() {
764 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000765 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000766}
767
768
769bool Object::IsStruct() {
770 if (!IsHeapObject()) return false;
771 switch (HeapObject::cast(this)->map()->instance_type()) {
772#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
773 STRUCT_LIST(MAKE_STRUCT_CASE)
774#undef MAKE_STRUCT_CASE
775 default: return false;
776 }
777}
778
779
780#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
781 bool Object::Is##Name() { \
782 return Object::IsHeapObject() \
783 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
784 }
785 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
786#undef MAKE_STRUCT_PREDICATE
787
788
789bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000790 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000791}
792
793
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000795 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
796}
797
798
799bool Object::IsTheHole() {
800 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801}
802
803
804bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000805 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806}
807
808
809bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000810 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000811}
812
813
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000814bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000816}
817
818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819double Object::Number() {
820 ASSERT(IsNumber());
821 return IsSmi()
822 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
823 : reinterpret_cast<HeapNumber*>(this)->value();
824}
825
826
lrn@chromium.org303ada72010-10-27 09:33:13 +0000827MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 if (IsSmi()) return this;
829 if (IsHeapNumber()) {
830 double value = HeapNumber::cast(this)->value();
831 int int_value = FastD2I(value);
832 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
833 return Smi::FromInt(int_value);
834 }
835 }
836 return Failure::Exception();
837}
838
839
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000840bool Object::HasSpecificClassOf(String* name) {
841 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000846 // GetElement can trigger a getter which can cause allocation.
847 // This was not always the case. This ASSERT is here to catch
848 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850 return GetElementWithReceiver(this, index);
851}
852
853
lrn@chromium.org303ada72010-10-27 09:33:13 +0000854Object* Object::GetElementNoExceptionThrown(uint32_t index) {
855 MaybeObject* maybe = GetElementWithReceiver(this, index);
856 ASSERT(!maybe->IsFailure());
857 Object* result = NULL; // Initialization to please compiler.
858 maybe->ToObject(&result);
859 return result;
860}
861
862
863MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 PropertyAttributes attributes;
865 return GetPropertyWithReceiver(this, key, &attributes);
866}
867
868
lrn@chromium.org303ada72010-10-27 09:33:13 +0000869MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870 return GetPropertyWithReceiver(this, key, attributes);
871}
872
873
874#define FIELD_ADDR(p, offset) \
875 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
876
877#define READ_FIELD(p, offset) \
878 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
879
880#define WRITE_FIELD(p, offset, value) \
881 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
882
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000883// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000884#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000885 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000886
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000887// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000888// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000889#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000890 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000892 } else { \
893 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000894 ASSERT(heap->InNewSpace(object) || \
895 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000896 Page::FromAddress(object->address())-> \
897 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000898 }
899
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900#ifndef V8_TARGET_ARCH_MIPS
901 #define READ_DOUBLE_FIELD(p, offset) \
902 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
903#else // V8_TARGET_ARCH_MIPS
904 // Prevent gcc from using load-double (mips ldc1) on (possibly)
905 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000906 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000907 union conversion {
908 double d;
909 uint32_t u[2];
910 } c;
911 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
912 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
913 return c.d;
914 }
915 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
916#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000917
lrn@chromium.org7516f052011-03-30 08:52:27 +0000918
919#ifndef V8_TARGET_ARCH_MIPS
920 #define WRITE_DOUBLE_FIELD(p, offset, value) \
921 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
922#else // V8_TARGET_ARCH_MIPS
923 // Prevent gcc from using store-double (mips sdc1) on (possibly)
924 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000925 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000926 double value) {
927 union conversion {
928 double d;
929 uint32_t u[2];
930 } c;
931 c.d = value;
932 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
933 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
934 }
935 #define WRITE_DOUBLE_FIELD(p, offset, value) \
936 write_double_field(p, offset, value)
937#endif // V8_TARGET_ARCH_MIPS
938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000939
940#define READ_INT_FIELD(p, offset) \
941 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
942
943#define WRITE_INT_FIELD(p, offset, value) \
944 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
945
ager@chromium.org3e875802009-06-29 08:26:34 +0000946#define READ_INTPTR_FIELD(p, offset) \
947 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
948
949#define WRITE_INTPTR_FIELD(p, offset, value) \
950 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
951
ager@chromium.org7c537e22008-10-16 08:43:32 +0000952#define READ_UINT32_FIELD(p, offset) \
953 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
954
955#define WRITE_UINT32_FIELD(p, offset, value) \
956 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
957
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958#define READ_SHORT_FIELD(p, offset) \
959 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
960
961#define WRITE_SHORT_FIELD(p, offset, value) \
962 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
963
964#define READ_BYTE_FIELD(p, offset) \
965 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
966
967#define WRITE_BYTE_FIELD(p, offset, value) \
968 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
969
970
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000971Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
972 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000973}
974
975
976int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000977 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000978}
979
980
981Smi* Smi::FromInt(int value) {
982 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000983 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000984 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000985 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000986 return reinterpret_cast<Smi*>(tagged_value);
987}
988
989
990Smi* Smi::FromIntptr(intptr_t value) {
991 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000992 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
993 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000994}
995
996
997Failure::Type Failure::type() const {
998 return static_cast<Type>(value() & kFailureTypeTagMask);
999}
1000
1001
1002bool Failure::IsInternalError() const {
1003 return type() == INTERNAL_ERROR;
1004}
1005
1006
1007bool Failure::IsOutOfMemoryException() const {
1008 return type() == OUT_OF_MEMORY_EXCEPTION;
1009}
1010
1011
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001012AllocationSpace Failure::allocation_space() const {
1013 ASSERT_EQ(RETRY_AFTER_GC, type());
1014 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1015 & kSpaceTagMask);
1016}
1017
1018
1019Failure* Failure::InternalError() {
1020 return Construct(INTERNAL_ERROR);
1021}
1022
1023
1024Failure* Failure::Exception() {
1025 return Construct(EXCEPTION);
1026}
1027
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001028
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001029Failure* Failure::OutOfMemoryException() {
1030 return Construct(OUT_OF_MEMORY_EXCEPTION);
1031}
1032
1033
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001034intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001035 return static_cast<intptr_t>(
1036 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037}
1038
1039
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001040Failure* Failure::RetryAfterGC() {
1041 return RetryAfterGC(NEW_SPACE);
1042}
1043
1044
1045Failure* Failure::RetryAfterGC(AllocationSpace space) {
1046 ASSERT((space & ~kSpaceTagMask) == 0);
1047 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001048}
1049
1050
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001051Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001052 uintptr_t info =
1053 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001054 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056}
1057
1058
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001059bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060#ifdef DEBUG
1061 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1062#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001063
1064#ifdef V8_TARGET_ARCH_X64
1065 // To be representable as a long smi, the value must be a 32-bit integer.
1066 bool result = (value == static_cast<int32_t>(value));
1067#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001068 // To be representable as an tagged small integer, the two
1069 // most-significant bits of 'value' must be either 00 or 11 due to
1070 // sign-extension. To check this we add 01 to the two
1071 // most-significant bits, and check if the most-significant bit is 0
1072 //
1073 // CAUTION: The original code below:
1074 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1075 // may lead to incorrect results according to the C language spec, and
1076 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1077 // compiler may produce undefined results in case of signed integer
1078 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001079 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001080#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001081 ASSERT(result == in_range);
1082 return result;
1083}
1084
1085
kasper.lund7276f142008-07-30 08:49:36 +00001086MapWord MapWord::FromMap(Map* map) {
1087 return MapWord(reinterpret_cast<uintptr_t>(map));
1088}
1089
1090
1091Map* MapWord::ToMap() {
1092 return reinterpret_cast<Map*>(value_);
1093}
1094
1095
1096bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001097 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001098}
1099
1100
1101MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001102 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1103 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001104}
1105
1106
1107HeapObject* MapWord::ToForwardingAddress() {
1108 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001109 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001110}
1111
1112
1113bool MapWord::IsMarked() {
1114 return (value_ & kMarkingMask) == 0;
1115}
1116
1117
1118void MapWord::SetMark() {
1119 value_ &= ~kMarkingMask;
1120}
1121
1122
1123void MapWord::ClearMark() {
1124 value_ |= kMarkingMask;
1125}
1126
1127
1128bool MapWord::IsOverflowed() {
1129 return (value_ & kOverflowMask) != 0;
1130}
1131
1132
1133void MapWord::SetOverflow() {
1134 value_ |= kOverflowMask;
1135}
1136
1137
1138void MapWord::ClearOverflow() {
1139 value_ &= ~kOverflowMask;
1140}
1141
1142
1143MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1144 // Offset is the distance in live bytes from the first live object in the
1145 // same page. The offset between two objects in the same page should not
1146 // exceed the object area size of a page.
1147 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1148
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001149 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001150 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1151
1152 Page* map_page = Page::FromAddress(map_address);
1153 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1154
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001155 uintptr_t map_page_offset =
1156 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001157
1158 uintptr_t encoding =
1159 (compact_offset << kForwardingOffsetShift) |
1160 (map_page_offset << kMapPageOffsetShift) |
1161 (map_page->mc_page_index << kMapPageIndexShift);
1162 return MapWord(encoding);
1163}
1164
1165
1166Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001167 int map_page_index =
1168 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001169 ASSERT_MAP_PAGE_INDEX(map_page_index);
1170
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001171 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001172 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1173 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001174
1175 return (map_space->PageAddress(map_page_index) + map_page_offset);
1176}
1177
1178
1179int MapWord::DecodeOffset() {
1180 // The offset field is represented in the kForwardingOffsetBits
1181 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001182 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1183 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1184 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001185}
1186
1187
1188MapWord MapWord::FromEncodedAddress(Address address) {
1189 return MapWord(reinterpret_cast<uintptr_t>(address));
1190}
1191
1192
1193Address MapWord::ToEncodedAddress() {
1194 return reinterpret_cast<Address>(value_);
1195}
1196
1197
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001198#ifdef DEBUG
1199void HeapObject::VerifyObjectField(int offset) {
1200 VerifyPointer(READ_FIELD(this, offset));
1201}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001202
1203void HeapObject::VerifySmiField(int offset) {
1204 ASSERT(READ_FIELD(this, offset)->IsSmi());
1205}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001206#endif
1207
1208
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001209Heap* HeapObject::GetHeap() {
1210 // During GC, the map pointer in HeapObject is used in various ways that
1211 // prevent us from retrieving Heap from the map.
1212 // Assert that we are not in GC, implement GC code in a way that it doesn't
1213 // pull heap from the map.
1214 ASSERT(HEAP->is_safe_to_read_maps());
1215 return map()->heap();
1216}
1217
1218
1219Isolate* HeapObject::GetIsolate() {
1220 return GetHeap()->isolate();
1221}
1222
1223
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001225 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001226}
1227
1228
1229void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001230 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001231}
1232
1233
kasper.lund7276f142008-07-30 08:49:36 +00001234MapWord HeapObject::map_word() {
1235 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1236}
1237
1238
1239void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001240 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001241 // here.
1242 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1243}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244
1245
1246HeapObject* HeapObject::FromAddress(Address address) {
1247 ASSERT_TAG_ALIGNED(address);
1248 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1249}
1250
1251
1252Address HeapObject::address() {
1253 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1254}
1255
1256
1257int HeapObject::Size() {
1258 return SizeFromMap(map());
1259}
1260
1261
1262void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1263 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1264 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1265}
1266
1267
1268void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1269 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1270}
1271
1272
kasper.lund7276f142008-07-30 08:49:36 +00001273bool HeapObject::IsMarked() {
1274 return map_word().IsMarked();
1275}
1276
1277
1278void HeapObject::SetMark() {
1279 ASSERT(!IsMarked());
1280 MapWord first_word = map_word();
1281 first_word.SetMark();
1282 set_map_word(first_word);
1283}
1284
1285
1286void HeapObject::ClearMark() {
1287 ASSERT(IsMarked());
1288 MapWord first_word = map_word();
1289 first_word.ClearMark();
1290 set_map_word(first_word);
1291}
1292
1293
1294bool HeapObject::IsOverflowed() {
1295 return map_word().IsOverflowed();
1296}
1297
1298
1299void HeapObject::SetOverflow() {
1300 MapWord first_word = map_word();
1301 first_word.SetOverflow();
1302 set_map_word(first_word);
1303}
1304
1305
1306void HeapObject::ClearOverflow() {
1307 ASSERT(IsOverflowed());
1308 MapWord first_word = map_word();
1309 first_word.ClearOverflow();
1310 set_map_word(first_word);
1311}
1312
1313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001314double HeapNumber::value() {
1315 return READ_DOUBLE_FIELD(this, kValueOffset);
1316}
1317
1318
1319void HeapNumber::set_value(double value) {
1320 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1321}
1322
1323
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001324int HeapNumber::get_exponent() {
1325 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1326 kExponentShift) - kExponentBias;
1327}
1328
1329
1330int HeapNumber::get_sign() {
1331 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1332}
1333
1334
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001335ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001336
1337
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001338HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001339 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001340 ASSERT(array->HasValidElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001341 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001342}
1343
1344
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001345void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001346 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001347 (value->map() == GetHeap()->fixed_array_map() ||
1348 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001349 ASSERT(map()->has_fast_double_elements() ==
1350 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001351 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001352 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001353 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001354}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001355
1356
1357void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001358 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1359 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001360}
1361
1362
1363void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001364 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001365 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1366 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367}
1368
1369
lrn@chromium.org303ada72010-10-27 09:33:13 +00001370MaybeObject* JSObject::ResetElements() {
1371 Object* obj;
1372 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1373 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1374 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001375 set_map(Map::cast(obj));
1376 initialize_elements();
1377 return this;
1378}
1379
1380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381ACCESSORS(Oddball, to_string, String, kToStringOffset)
1382ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1383
1384
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001385byte Oddball::kind() {
1386 return READ_BYTE_FIELD(this, kKindOffset);
1387}
1388
1389
1390void Oddball::set_kind(byte value) {
1391 WRITE_BYTE_FIELD(this, kKindOffset, value);
1392}
1393
1394
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001395Object* JSGlobalPropertyCell::value() {
1396 return READ_FIELD(this, kValueOffset);
1397}
1398
1399
1400void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1401 // The write barrier is not used for global property cells.
1402 ASSERT(!val->IsJSGlobalPropertyCell());
1403 WRITE_FIELD(this, kValueOffset, val);
1404}
1405
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001408 InstanceType type = map()->instance_type();
1409 // Check for the most common kind of JavaScript object before
1410 // falling into the generic switch. This speeds up the internal
1411 // field operations considerably on average.
1412 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1413 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001414 case JS_GLOBAL_PROXY_TYPE:
1415 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416 case JS_GLOBAL_OBJECT_TYPE:
1417 return JSGlobalObject::kSize;
1418 case JS_BUILTINS_OBJECT_TYPE:
1419 return JSBuiltinsObject::kSize;
1420 case JS_FUNCTION_TYPE:
1421 return JSFunction::kSize;
1422 case JS_VALUE_TYPE:
1423 return JSValue::kSize;
1424 case JS_ARRAY_TYPE:
1425 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001426 case JS_WEAK_MAP_TYPE:
1427 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001428 case JS_REGEXP_TYPE:
1429 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001430 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001432 case JS_MESSAGE_OBJECT_TYPE:
1433 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001434 default:
1435 UNREACHABLE();
1436 return 0;
1437 }
1438}
1439
1440
1441int JSObject::GetInternalFieldCount() {
1442 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001443 // Make sure to adjust for the number of in-object properties. These
1444 // properties do contribute to the size, but are not internal fields.
1445 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1446 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447}
1448
1449
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001450int JSObject::GetInternalFieldOffset(int index) {
1451 ASSERT(index < GetInternalFieldCount() && index >= 0);
1452 return GetHeaderSize() + (kPointerSize * index);
1453}
1454
1455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456Object* JSObject::GetInternalField(int index) {
1457 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001458 // Internal objects do follow immediately after the header, whereas in-object
1459 // properties are at the end of the object. Therefore there is no need
1460 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1462}
1463
1464
1465void JSObject::SetInternalField(int index, Object* value) {
1466 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001467 // Internal objects do follow immediately after the header, whereas in-object
1468 // properties are at the end of the object. Therefore there is no need
1469 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001470 int offset = GetHeaderSize() + (kPointerSize * index);
1471 WRITE_FIELD(this, offset, value);
1472 WRITE_BARRIER(this, offset);
1473}
1474
1475
ager@chromium.org7c537e22008-10-16 08:43:32 +00001476// Access fast-case object properties at index. The use of these routines
1477// is needed to correctly distinguish between properties stored in-object and
1478// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001479Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001480 // Adjust for the number of properties stored in the object.
1481 index -= map()->inobject_properties();
1482 if (index < 0) {
1483 int offset = map()->instance_size() + (index * kPointerSize);
1484 return READ_FIELD(this, offset);
1485 } else {
1486 ASSERT(index < properties()->length());
1487 return properties()->get(index);
1488 }
1489}
1490
1491
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001492Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001493 // Adjust for the number of properties stored in the object.
1494 index -= map()->inobject_properties();
1495 if (index < 0) {
1496 int offset = map()->instance_size() + (index * kPointerSize);
1497 WRITE_FIELD(this, offset, value);
1498 WRITE_BARRIER(this, offset);
1499 } else {
1500 ASSERT(index < properties()->length());
1501 properties()->set(index, value);
1502 }
1503 return value;
1504}
1505
1506
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001507int JSObject::GetInObjectPropertyOffset(int index) {
1508 // Adjust for the number of properties stored in the object.
1509 index -= map()->inobject_properties();
1510 ASSERT(index < 0);
1511 return map()->instance_size() + (index * kPointerSize);
1512}
1513
1514
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001515Object* JSObject::InObjectPropertyAt(int index) {
1516 // Adjust for the number of properties stored in the object.
1517 index -= map()->inobject_properties();
1518 ASSERT(index < 0);
1519 int offset = map()->instance_size() + (index * kPointerSize);
1520 return READ_FIELD(this, offset);
1521}
1522
1523
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001524Object* JSObject::InObjectPropertyAtPut(int index,
1525 Object* value,
1526 WriteBarrierMode mode) {
1527 // Adjust for the number of properties stored in the object.
1528 index -= map()->inobject_properties();
1529 ASSERT(index < 0);
1530 int offset = map()->instance_size() + (index * kPointerSize);
1531 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001532 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001533 return value;
1534}
1535
1536
1537
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001538void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001539 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001541 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001542 }
1543}
1544
1545
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001546bool JSObject::HasFastProperties() {
1547 return !properties()->IsDictionary();
1548}
1549
1550
1551int JSObject::MaxFastProperties() {
1552 // Allow extra fast properties if the object has more than
1553 // kMaxFastProperties in-object properties. When this is the case,
1554 // it is very unlikely that the object is being used as a dictionary
1555 // and there is a good chance that allowing more map transitions
1556 // will be worth it.
1557 return Max(map()->inobject_properties(), kMaxFastProperties);
1558}
1559
1560
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001562 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001563 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001564 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565 }
1566}
1567
1568
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001569bool Object::ToArrayIndex(uint32_t* index) {
1570 if (IsSmi()) {
1571 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001572 if (value < 0) return false;
1573 *index = value;
1574 return true;
1575 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001576 if (IsHeapNumber()) {
1577 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578 uint32_t uint_value = static_cast<uint32_t>(value);
1579 if (value == static_cast<double>(uint_value)) {
1580 *index = uint_value;
1581 return true;
1582 }
1583 }
1584 return false;
1585}
1586
1587
1588bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1589 if (!this->IsJSValue()) return false;
1590
1591 JSValue* js_value = JSValue::cast(this);
1592 if (!js_value->value()->IsString()) return false;
1593
1594 String* str = String::cast(js_value->value());
1595 if (index >= (uint32_t)str->length()) return false;
1596
1597 return true;
1598}
1599
1600
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001601FixedArrayBase* FixedArrayBase::cast(Object* object) {
1602 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1603 return reinterpret_cast<FixedArrayBase*>(object);
1604}
1605
1606
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607Object* FixedArray::get(int index) {
1608 ASSERT(index >= 0 && index < this->length());
1609 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1610}
1611
1612
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001613void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001614 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001615 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001616 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1617 int offset = kHeaderSize + index * kPointerSize;
1618 WRITE_FIELD(this, offset, value);
1619}
1620
1621
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001623 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624 ASSERT(index >= 0 && index < this->length());
1625 int offset = kHeaderSize + index * kPointerSize;
1626 WRITE_FIELD(this, offset, value);
1627 WRITE_BARRIER(this, offset);
1628}
1629
1630
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001631inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1632 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1633}
1634
1635
1636inline double FixedDoubleArray::hole_nan_as_double() {
1637 return BitCast<double, uint64_t>(kHoleNanInt64);
1638}
1639
1640
1641inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1642 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1643 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1644 return OS::nan_value();
1645}
1646
1647
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001648double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001649 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1650 map() != HEAP->fixed_array_map());
1651 ASSERT(index >= 0 && index < this->length());
1652 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1653 ASSERT(!is_the_hole_nan(result));
1654 return result;
1655}
1656
1657
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001658MaybeObject* FixedDoubleArray::get(int index) {
1659 if (is_the_hole(index)) {
1660 return GetHeap()->the_hole_value();
1661 } else {
1662 return GetHeap()->NumberFromDouble(get_scalar(index));
1663 }
1664}
1665
1666
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001667void FixedDoubleArray::set(int index, double value) {
1668 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1669 map() != HEAP->fixed_array_map());
1670 int offset = kHeaderSize + index * kDoubleSize;
1671 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1672 WRITE_DOUBLE_FIELD(this, offset, value);
1673}
1674
1675
1676void FixedDoubleArray::set_the_hole(int index) {
1677 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1678 map() != HEAP->fixed_array_map());
1679 int offset = kHeaderSize + index * kDoubleSize;
1680 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1681}
1682
1683
1684bool FixedDoubleArray::is_the_hole(int index) {
1685 int offset = kHeaderSize + index * kDoubleSize;
1686 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1687}
1688
1689
1690void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1691 int old_length = from->length();
1692 ASSERT(old_length < length());
1693 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1694 FIELD_ADDR(from, kHeaderSize),
1695 old_length * kDoubleSize);
1696 int offset = kHeaderSize + old_length * kDoubleSize;
1697 for (int current = from->length(); current < length(); ++current) {
1698 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1699 offset += kDoubleSize;
1700 }
1701}
1702
1703
1704void FixedDoubleArray::Initialize(FixedArray* from) {
1705 int old_length = from->length();
1706 ASSERT(old_length < length());
1707 for (int i = 0; i < old_length; i++) {
1708 Object* hole_or_object = from->get(i);
1709 if (hole_or_object->IsTheHole()) {
1710 set_the_hole(i);
1711 } else {
1712 set(i, hole_or_object->Number());
1713 }
1714 }
1715 int offset = kHeaderSize + old_length * kDoubleSize;
1716 for (int current = from->length(); current < length(); ++current) {
1717 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1718 offset += kDoubleSize;
1719 }
1720}
1721
1722
1723void FixedDoubleArray::Initialize(NumberDictionary* from) {
1724 int offset = kHeaderSize;
1725 for (int current = 0; current < length(); ++current) {
1726 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1727 offset += kDoubleSize;
1728 }
1729 for (int i = 0; i < from->Capacity(); i++) {
1730 Object* key = from->KeyAt(i);
1731 if (key->IsNumber()) {
1732 uint32_t entry = static_cast<uint32_t>(key->Number());
1733 set(entry, from->ValueAt(i)->Number());
1734 }
1735 }
1736}
1737
1738
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001739WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001740 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741 return UPDATE_WRITE_BARRIER;
1742}
1743
1744
1745void FixedArray::set(int index,
1746 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001747 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001748 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749 ASSERT(index >= 0 && index < this->length());
1750 int offset = kHeaderSize + index * kPointerSize;
1751 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001752 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753}
1754
1755
1756void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001757 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001758 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001759 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1761}
1762
1763
1764void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001765 ASSERT(map() != HEAP->fixed_cow_array_map());
1766 set_undefined(GetHeap(), index);
1767}
1768
1769
1770void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001772 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001773 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001774 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001775}
1776
1777
ager@chromium.org236ad962008-09-25 09:45:57 +00001778void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001779 set_null(GetHeap(), index);
1780}
1781
1782
1783void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001784 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001785 ASSERT(!heap->InNewSpace(heap->null_value()));
1786 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001787}
1788
1789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001791 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001793 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1794 WRITE_FIELD(this,
1795 kHeaderSize + index * kPointerSize,
1796 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797}
1798
1799
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001800void FixedArray::set_unchecked(int index, Smi* value) {
1801 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1802 int offset = kHeaderSize + index * kPointerSize;
1803 WRITE_FIELD(this, offset, value);
1804}
1805
1806
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001807void FixedArray::set_unchecked(Heap* heap,
1808 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001809 Object* value,
1810 WriteBarrierMode mode) {
1811 int offset = kHeaderSize + index * kPointerSize;
1812 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001813 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001814}
1815
1816
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001817void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001818 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001819 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1820 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001821}
1822
1823
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001824Object** FixedArray::data_start() {
1825 return HeapObject::RawField(this, kHeaderSize);
1826}
1827
1828
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001829bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001830 ASSERT(this->IsSmi() ||
1831 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001833 return this->IsSmi() || length() <= kFirstIndex;
1834}
1835
1836
1837int DescriptorArray::bit_field3_storage() {
1838 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1839 return Smi::cast(storage)->value();
1840}
1841
1842void DescriptorArray::set_bit_field3_storage(int value) {
1843 ASSERT(!IsEmpty());
1844 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001845}
1846
1847
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1849 Object* tmp = array->get(first);
1850 fast_set(array, first, array->get(second));
1851 fast_set(array, second, tmp);
1852}
1853
1854
1855int DescriptorArray::Search(String* name) {
1856 SLOW_ASSERT(IsSortedNoDuplicates());
1857
1858 // Check for empty descriptor array.
1859 int nof = number_of_descriptors();
1860 if (nof == 0) return kNotFound;
1861
1862 // Fast case: do linear search for small arrays.
1863 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001864 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001865 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001866 }
1867
1868 // Slow case: perform binary search.
1869 return BinarySearch(name, 0, nof - 1);
1870}
1871
1872
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001873int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001874 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001875 if (number == DescriptorLookupCache::kAbsent) {
1876 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001877 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001878 }
1879 return number;
1880}
1881
1882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883String* DescriptorArray::GetKey(int descriptor_number) {
1884 ASSERT(descriptor_number < number_of_descriptors());
1885 return String::cast(get(ToKeyIndex(descriptor_number)));
1886}
1887
1888
1889Object* DescriptorArray::GetValue(int descriptor_number) {
1890 ASSERT(descriptor_number < number_of_descriptors());
1891 return GetContentArray()->get(ToValueIndex(descriptor_number));
1892}
1893
1894
1895Smi* DescriptorArray::GetDetails(int descriptor_number) {
1896 ASSERT(descriptor_number < number_of_descriptors());
1897 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1898}
1899
1900
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001901PropertyType DescriptorArray::GetType(int descriptor_number) {
1902 ASSERT(descriptor_number < number_of_descriptors());
1903 return PropertyDetails(GetDetails(descriptor_number)).type();
1904}
1905
1906
1907int DescriptorArray::GetFieldIndex(int descriptor_number) {
1908 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1909}
1910
1911
1912JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1913 return JSFunction::cast(GetValue(descriptor_number));
1914}
1915
1916
1917Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1918 ASSERT(GetType(descriptor_number) == CALLBACKS);
1919 return GetValue(descriptor_number);
1920}
1921
1922
1923AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1924 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001925 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1926 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001927}
1928
1929
1930bool DescriptorArray::IsProperty(int descriptor_number) {
1931 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1932}
1933
1934
1935bool DescriptorArray::IsTransition(int descriptor_number) {
1936 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001937 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1938 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001939}
1940
1941
1942bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1943 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1944}
1945
1946
1947bool DescriptorArray::IsDontEnum(int descriptor_number) {
1948 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1949}
1950
1951
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001952void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1953 desc->Init(GetKey(descriptor_number),
1954 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001955 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956}
1957
1958
1959void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1960 // Range check.
1961 ASSERT(descriptor_number < number_of_descriptors());
1962
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001963 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1965 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001966
1967 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1968 FixedArray* content_array = GetContentArray();
1969 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1970 fast_set(content_array, ToDetailsIndex(descriptor_number),
1971 desc->GetDetails().AsSmi());
1972}
1973
1974
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001975void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1976 Descriptor desc;
1977 src->Get(src_index, &desc);
1978 Set(index, &desc);
1979}
1980
1981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001982void DescriptorArray::Swap(int first, int second) {
1983 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1984 FixedArray* content_array = GetContentArray();
1985 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1986 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1987}
1988
1989
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001990template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001991int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1992 const int kMinCapacity = 32;
1993 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1994 if (capacity < kMinCapacity) {
1995 capacity = kMinCapacity; // Guarantee min capacity.
1996 }
1997 return capacity;
1998}
1999
2000
2001template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002002int HashTable<Shape, Key>::FindEntry(Key key) {
2003 return FindEntry(GetIsolate(), key);
2004}
2005
2006
2007// Find entry for key otherwise return kNotFound.
2008template<typename Shape, typename Key>
2009int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2010 uint32_t capacity = Capacity();
2011 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2012 uint32_t count = 1;
2013 // EnsureCapacity will guarantee the hash table is never full.
2014 while (true) {
2015 Object* element = KeyAt(entry);
2016 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2017 if (element != isolate->heap()->null_value() &&
2018 Shape::IsMatch(key, element)) return entry;
2019 entry = NextProbe(entry, count++, capacity);
2020 }
2021 return kNotFound;
2022}
2023
2024
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002025bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002026 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027 if (!max_index_object->IsSmi()) return false;
2028 return 0 !=
2029 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2030}
2031
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002032uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002034 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035 if (!max_index_object->IsSmi()) return 0;
2036 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2037 return value >> kRequiresSlowElementsTagSize;
2038}
2039
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002040void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002041 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002042}
2043
2044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045// ------------------------------------
2046// Cast operations
2047
2048
2049CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002050CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002051CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052CAST_ACCESSOR(DeoptimizationInputData)
2053CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002054CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002055CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002056CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002057CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002058CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002059CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002060CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002061CAST_ACCESSOR(String)
2062CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002063CAST_ACCESSOR(SeqAsciiString)
2064CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002065CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002066CAST_ACCESSOR(ExternalString)
2067CAST_ACCESSOR(ExternalAsciiString)
2068CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002069CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070CAST_ACCESSOR(JSObject)
2071CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002072CAST_ACCESSOR(HeapObject)
2073CAST_ACCESSOR(HeapNumber)
2074CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002075CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076CAST_ACCESSOR(SharedFunctionInfo)
2077CAST_ACCESSOR(Map)
2078CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002079CAST_ACCESSOR(GlobalObject)
2080CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002081CAST_ACCESSOR(JSGlobalObject)
2082CAST_ACCESSOR(JSBuiltinsObject)
2083CAST_ACCESSOR(Code)
2084CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002085CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002086CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002087CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002088CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002089CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002091CAST_ACCESSOR(ExternalArray)
2092CAST_ACCESSOR(ExternalByteArray)
2093CAST_ACCESSOR(ExternalUnsignedByteArray)
2094CAST_ACCESSOR(ExternalShortArray)
2095CAST_ACCESSOR(ExternalUnsignedShortArray)
2096CAST_ACCESSOR(ExternalIntArray)
2097CAST_ACCESSOR(ExternalUnsignedIntArray)
2098CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002099CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002100CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101CAST_ACCESSOR(Struct)
2102
2103
2104#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2105 STRUCT_LIST(MAKE_STRUCT_CAST)
2106#undef MAKE_STRUCT_CAST
2107
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002108
2109template <typename Shape, typename Key>
2110HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111 ASSERT(obj->IsHashTable());
2112 return reinterpret_cast<HashTable*>(obj);
2113}
2114
2115
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002116SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002117SMI_ACCESSORS(ByteArray, length, kLengthOffset)
2118
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002119// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
whesse@chromium.org7b260152011-06-20 15:33:18 +00002120// subsequently unify H{Fixed,External}ArrayLength).
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002121INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122
2123
ager@chromium.orgac091b72010-05-05 07:34:42 +00002124SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002125
2126
2127uint32_t String::hash_field() {
2128 return READ_UINT32_FIELD(this, kHashFieldOffset);
2129}
2130
2131
2132void String::set_hash_field(uint32_t value) {
2133 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002134#if V8_HOST_ARCH_64_BIT
2135 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2136#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002137}
2138
2139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140bool String::Equals(String* other) {
2141 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002142 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2143 return false;
2144 }
2145 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146}
2147
2148
lrn@chromium.org303ada72010-10-27 09:33:13 +00002149MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002150 if (!StringShape(this).IsCons()) return this;
2151 ConsString* cons = ConsString::cast(this);
2152 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002153 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154}
2155
2156
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002157String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002158 MaybeObject* flat = TryFlatten(pretenure);
2159 Object* successfully_flattened;
2160 if (flat->ToObject(&successfully_flattened)) {
2161 return String::cast(successfully_flattened);
2162 }
2163 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002164}
2165
2166
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002167uint16_t String::Get(int index) {
2168 ASSERT(index >= 0 && index < length());
2169 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002170 case kSeqStringTag | kAsciiStringTag:
2171 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2172 case kSeqStringTag | kTwoByteStringTag:
2173 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2174 case kConsStringTag | kAsciiStringTag:
2175 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002177 case kExternalStringTag | kAsciiStringTag:
2178 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2179 case kExternalStringTag | kTwoByteStringTag:
2180 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002181 default:
2182 break;
2183 }
2184
2185 UNREACHABLE();
2186 return 0;
2187}
2188
2189
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002190void String::Set(int index, uint16_t value) {
2191 ASSERT(index >= 0 && index < length());
2192 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193
ager@chromium.org5ec48922009-05-05 07:25:34 +00002194 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002195 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2196 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002197}
2198
2199
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002200bool String::IsFlat() {
2201 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002202 case kConsStringTag: {
2203 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002204 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002205 return second->length() == 0;
2206 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002207 default:
2208 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209 }
2210}
2211
2212
ager@chromium.org7c537e22008-10-16 08:43:32 +00002213uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 ASSERT(index >= 0 && index < length());
2215 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2216}
2217
2218
ager@chromium.org7c537e22008-10-16 08:43:32 +00002219void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002220 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2221 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2222 static_cast<byte>(value));
2223}
2224
2225
ager@chromium.org7c537e22008-10-16 08:43:32 +00002226Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227 return FIELD_ADDR(this, kHeaderSize);
2228}
2229
2230
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002231char* SeqAsciiString::GetChars() {
2232 return reinterpret_cast<char*>(GetCharsAddress());
2233}
2234
2235
ager@chromium.org7c537e22008-10-16 08:43:32 +00002236Address SeqTwoByteString::GetCharsAddress() {
2237 return FIELD_ADDR(this, kHeaderSize);
2238}
2239
2240
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002241uc16* SeqTwoByteString::GetChars() {
2242 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2243}
2244
2245
ager@chromium.org7c537e22008-10-16 08:43:32 +00002246uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002247 ASSERT(index >= 0 && index < length());
2248 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2249}
2250
2251
ager@chromium.org7c537e22008-10-16 08:43:32 +00002252void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253 ASSERT(index >= 0 && index < length());
2254 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2255}
2256
2257
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002258int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002259 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260}
2261
2262
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002263int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002264 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265}
2266
2267
ager@chromium.org870a0b62008-11-04 11:43:05 +00002268String* ConsString::first() {
2269 return String::cast(READ_FIELD(this, kFirstOffset));
2270}
2271
2272
2273Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 return READ_FIELD(this, kFirstOffset);
2275}
2276
2277
ager@chromium.org870a0b62008-11-04 11:43:05 +00002278void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002280 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281}
2282
2283
ager@chromium.org870a0b62008-11-04 11:43:05 +00002284String* ConsString::second() {
2285 return String::cast(READ_FIELD(this, kSecondOffset));
2286}
2287
2288
2289Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290 return READ_FIELD(this, kSecondOffset);
2291}
2292
2293
ager@chromium.org870a0b62008-11-04 11:43:05 +00002294void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002296 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297}
2298
2299
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2301 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2302}
2303
2304
2305void ExternalAsciiString::set_resource(
2306 ExternalAsciiString::Resource* resource) {
2307 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2308}
2309
2310
2311ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2312 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2313}
2314
2315
2316void ExternalTwoByteString::set_resource(
2317 ExternalTwoByteString::Resource* resource) {
2318 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2319}
2320
2321
ager@chromium.orgac091b72010-05-05 07:34:42 +00002322void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002323 set_finger_index(kEntriesIndex);
2324 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002325}
2326
2327
2328void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002329 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002330 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002331 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002332 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002333 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002334 MakeZeroSize();
2335}
2336
2337
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002338int JSFunctionResultCache::size() {
2339 return Smi::cast(get(kCacheSizeIndex))->value();
2340}
2341
2342
2343void JSFunctionResultCache::set_size(int size) {
2344 set(kCacheSizeIndex, Smi::FromInt(size));
2345}
2346
2347
2348int JSFunctionResultCache::finger_index() {
2349 return Smi::cast(get(kFingerIndex))->value();
2350}
2351
2352
2353void JSFunctionResultCache::set_finger_index(int finger_index) {
2354 set(kFingerIndex, Smi::FromInt(finger_index));
2355}
2356
2357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358byte ByteArray::get(int index) {
2359 ASSERT(index >= 0 && index < this->length());
2360 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2361}
2362
2363
2364void ByteArray::set(int index, byte value) {
2365 ASSERT(index >= 0 && index < this->length());
2366 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2367}
2368
2369
2370int ByteArray::get_int(int index) {
2371 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2372 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2373}
2374
2375
2376ByteArray* ByteArray::FromDataStartAddress(Address address) {
2377 ASSERT_TAG_ALIGNED(address);
2378 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2379}
2380
2381
2382Address ByteArray::GetDataStartAddress() {
2383 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2384}
2385
2386
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002387uint8_t* ExternalPixelArray::external_pixel_pointer() {
2388 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002389}
2390
2391
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002392uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002393 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002394 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002395 return ptr[index];
2396}
2397
2398
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002399MaybeObject* ExternalPixelArray::get(int index) {
2400 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2401}
2402
2403
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002404void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002405 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002406 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002407 ptr[index] = value;
2408}
2409
2410
ager@chromium.org3811b432009-10-28 14:53:37 +00002411void* ExternalArray::external_pointer() {
2412 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2413 return reinterpret_cast<void*>(ptr);
2414}
2415
2416
2417void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2418 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2419 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2420}
2421
2422
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002423int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002424 ASSERT((index >= 0) && (index < this->length()));
2425 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2426 return ptr[index];
2427}
2428
2429
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002430MaybeObject* ExternalByteArray::get(int index) {
2431 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2432}
2433
2434
ager@chromium.org3811b432009-10-28 14:53:37 +00002435void ExternalByteArray::set(int index, int8_t value) {
2436 ASSERT((index >= 0) && (index < this->length()));
2437 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2438 ptr[index] = value;
2439}
2440
2441
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002442uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002443 ASSERT((index >= 0) && (index < this->length()));
2444 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2445 return ptr[index];
2446}
2447
2448
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002449MaybeObject* ExternalUnsignedByteArray::get(int index) {
2450 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2451}
2452
2453
ager@chromium.org3811b432009-10-28 14:53:37 +00002454void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2455 ASSERT((index >= 0) && (index < this->length()));
2456 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2457 ptr[index] = value;
2458}
2459
2460
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002461int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002462 ASSERT((index >= 0) && (index < this->length()));
2463 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2464 return ptr[index];
2465}
2466
2467
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002468MaybeObject* ExternalShortArray::get(int index) {
2469 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2470}
2471
2472
ager@chromium.org3811b432009-10-28 14:53:37 +00002473void ExternalShortArray::set(int index, int16_t value) {
2474 ASSERT((index >= 0) && (index < this->length()));
2475 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2476 ptr[index] = value;
2477}
2478
2479
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002480uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002481 ASSERT((index >= 0) && (index < this->length()));
2482 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2483 return ptr[index];
2484}
2485
2486
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002487MaybeObject* ExternalUnsignedShortArray::get(int index) {
2488 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2489}
2490
2491
ager@chromium.org3811b432009-10-28 14:53:37 +00002492void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2493 ASSERT((index >= 0) && (index < this->length()));
2494 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2495 ptr[index] = value;
2496}
2497
2498
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002499int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002500 ASSERT((index >= 0) && (index < this->length()));
2501 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2502 return ptr[index];
2503}
2504
2505
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002506MaybeObject* ExternalIntArray::get(int index) {
2507 return GetHeap()->NumberFromInt32(get_scalar(index));
2508}
2509
2510
ager@chromium.org3811b432009-10-28 14:53:37 +00002511void ExternalIntArray::set(int index, int32_t value) {
2512 ASSERT((index >= 0) && (index < this->length()));
2513 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2514 ptr[index] = value;
2515}
2516
2517
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002518uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002519 ASSERT((index >= 0) && (index < this->length()));
2520 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2521 return ptr[index];
2522}
2523
2524
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002525MaybeObject* ExternalUnsignedIntArray::get(int index) {
2526 return GetHeap()->NumberFromUint32(get_scalar(index));
2527}
2528
2529
ager@chromium.org3811b432009-10-28 14:53:37 +00002530void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2531 ASSERT((index >= 0) && (index < this->length()));
2532 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2533 ptr[index] = value;
2534}
2535
2536
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002537float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002538 ASSERT((index >= 0) && (index < this->length()));
2539 float* ptr = static_cast<float*>(external_pointer());
2540 return ptr[index];
2541}
2542
2543
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002544MaybeObject* ExternalFloatArray::get(int index) {
2545 return GetHeap()->NumberFromDouble(get_scalar(index));
2546}
2547
2548
ager@chromium.org3811b432009-10-28 14:53:37 +00002549void ExternalFloatArray::set(int index, float value) {
2550 ASSERT((index >= 0) && (index < this->length()));
2551 float* ptr = static_cast<float*>(external_pointer());
2552 ptr[index] = value;
2553}
2554
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002555
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002556double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002557 ASSERT((index >= 0) && (index < this->length()));
2558 double* ptr = static_cast<double*>(external_pointer());
2559 return ptr[index];
2560}
2561
2562
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002563MaybeObject* ExternalDoubleArray::get(int index) {
2564 return GetHeap()->NumberFromDouble(get_scalar(index));
2565}
2566
2567
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002568void ExternalDoubleArray::set(int index, double value) {
2569 ASSERT((index >= 0) && (index < this->length()));
2570 double* ptr = static_cast<double*>(external_pointer());
2571 ptr[index] = value;
2572}
2573
2574
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002575int Map::visitor_id() {
2576 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2577}
2578
2579
2580void Map::set_visitor_id(int id) {
2581 ASSERT(0 <= id && id < 256);
2582 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2583}
2584
ager@chromium.org3811b432009-10-28 14:53:37 +00002585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002587 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2588}
2589
2590
2591int Map::inobject_properties() {
2592 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002593}
2594
2595
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002596int Map::pre_allocated_property_fields() {
2597 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2598}
2599
2600
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002601int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002602 int instance_size = map->instance_size();
2603 if (instance_size != kVariableSizeSentinel) return instance_size;
2604 // We can ignore the "symbol" bit becase it is only set for symbols
2605 // and implies a string type.
2606 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002607 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002609 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002611 if (instance_type == ASCII_STRING_TYPE) {
2612 return SeqAsciiString::SizeFor(
2613 reinterpret_cast<SeqAsciiString*>(this)->length());
2614 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002615 if (instance_type == BYTE_ARRAY_TYPE) {
2616 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2617 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002618 if (instance_type == STRING_TYPE) {
2619 return SeqTwoByteString::SizeFor(
2620 reinterpret_cast<SeqTwoByteString*>(this)->length());
2621 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002622 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2623 return FixedDoubleArray::SizeFor(
2624 reinterpret_cast<FixedDoubleArray*>(this)->length());
2625 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002626 ASSERT(instance_type == CODE_TYPE);
2627 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002628}
2629
2630
2631void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002632 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002633 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002634 ASSERT(0 <= value && value < 256);
2635 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2636}
2637
2638
ager@chromium.org7c537e22008-10-16 08:43:32 +00002639void Map::set_inobject_properties(int value) {
2640 ASSERT(0 <= value && value < 256);
2641 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2642}
2643
2644
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002645void Map::set_pre_allocated_property_fields(int value) {
2646 ASSERT(0 <= value && value < 256);
2647 WRITE_BYTE_FIELD(this,
2648 kPreAllocatedPropertyFieldsOffset,
2649 static_cast<byte>(value));
2650}
2651
2652
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653InstanceType Map::instance_type() {
2654 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2655}
2656
2657
2658void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2660}
2661
2662
2663int Map::unused_property_fields() {
2664 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2665}
2666
2667
2668void Map::set_unused_property_fields(int value) {
2669 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2670}
2671
2672
2673byte Map::bit_field() {
2674 return READ_BYTE_FIELD(this, kBitFieldOffset);
2675}
2676
2677
2678void Map::set_bit_field(byte value) {
2679 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2680}
2681
2682
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002683byte Map::bit_field2() {
2684 return READ_BYTE_FIELD(this, kBitField2Offset);
2685}
2686
2687
2688void Map::set_bit_field2(byte value) {
2689 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2690}
2691
2692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002693void Map::set_non_instance_prototype(bool value) {
2694 if (value) {
2695 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2696 } else {
2697 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2698 }
2699}
2700
2701
2702bool Map::has_non_instance_prototype() {
2703 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2704}
2705
2706
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002707void Map::set_function_with_prototype(bool value) {
2708 if (value) {
2709 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2710 } else {
2711 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2712 }
2713}
2714
2715
2716bool Map::function_with_prototype() {
2717 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2718}
2719
2720
ager@chromium.org870a0b62008-11-04 11:43:05 +00002721void Map::set_is_access_check_needed(bool access_check_needed) {
2722 if (access_check_needed) {
2723 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2724 } else {
2725 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2726 }
2727}
2728
2729
2730bool Map::is_access_check_needed() {
2731 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2732}
2733
2734
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002735void Map::set_is_extensible(bool value) {
2736 if (value) {
2737 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2738 } else {
2739 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2740 }
2741}
2742
2743bool Map::is_extensible() {
2744 return ((1 << kIsExtensible) & bit_field2()) != 0;
2745}
2746
2747
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002748void Map::set_attached_to_shared_function_info(bool value) {
2749 if (value) {
2750 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2751 } else {
2752 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2753 }
2754}
2755
2756bool Map::attached_to_shared_function_info() {
2757 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2758}
2759
2760
2761void Map::set_is_shared(bool value) {
2762 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002763 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002764 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002765 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002766 }
2767}
2768
2769bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002770 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002771}
2772
2773
2774JSFunction* Map::unchecked_constructor() {
2775 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2776}
2777
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002778
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002779FixedArray* Map::unchecked_prototype_transitions() {
2780 return reinterpret_cast<FixedArray*>(
2781 READ_FIELD(this, kPrototypeTransitionsOffset));
2782}
2783
2784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785Code::Flags Code::flags() {
2786 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2787}
2788
2789
2790void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002791 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002792 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002793 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2794 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795 ExtractArgumentsCountFromFlags(flags) >= 0);
2796 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2797}
2798
2799
2800Code::Kind Code::kind() {
2801 return ExtractKindFromFlags(flags());
2802}
2803
2804
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002805InLoopFlag Code::ic_in_loop() {
2806 return ExtractICInLoopFromFlags(flags());
2807}
2808
2809
kasper.lund7276f142008-07-30 08:49:36 +00002810InlineCacheState Code::ic_state() {
2811 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812 // Only allow uninitialized or debugger states for non-IC code
2813 // objects. This is used in the debugger to determine whether or not
2814 // a call to code object has been replaced with a debug break call.
2815 ASSERT(is_inline_cache_stub() ||
2816 result == UNINITIALIZED ||
2817 result == DEBUG_BREAK ||
2818 result == DEBUG_PREPARE_STEP_IN);
2819 return result;
2820}
2821
2822
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002823Code::ExtraICState Code::extra_ic_state() {
2824 ASSERT(is_inline_cache_stub());
2825 return ExtractExtraICStateFromFlags(flags());
2826}
2827
2828
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002829PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002830 return ExtractTypeFromFlags(flags());
2831}
2832
2833
2834int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002835 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836 return ExtractArgumentsCountFromFlags(flags());
2837}
2838
2839
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002840int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002842 kind() == UNARY_OP_IC ||
2843 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002844 kind() == COMPARE_IC ||
2845 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002846 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002847}
2848
2849
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002850void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002851 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002852 kind() == UNARY_OP_IC ||
2853 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002854 kind() == COMPARE_IC ||
2855 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002856 ASSERT(0 <= major && major < 256);
2857 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858}
2859
2860
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002861bool Code::optimizable() {
2862 ASSERT(kind() == FUNCTION);
2863 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2864}
2865
2866
2867void Code::set_optimizable(bool value) {
2868 ASSERT(kind() == FUNCTION);
2869 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2870}
2871
2872
2873bool Code::has_deoptimization_support() {
2874 ASSERT(kind() == FUNCTION);
2875 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2876}
2877
2878
2879void Code::set_has_deoptimization_support(bool value) {
2880 ASSERT(kind() == FUNCTION);
2881 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2882}
2883
2884
2885int Code::allow_osr_at_loop_nesting_level() {
2886 ASSERT(kind() == FUNCTION);
2887 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2888}
2889
2890
2891void Code::set_allow_osr_at_loop_nesting_level(int level) {
2892 ASSERT(kind() == FUNCTION);
2893 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2894 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2895}
2896
2897
2898unsigned Code::stack_slots() {
2899 ASSERT(kind() == OPTIMIZED_FUNCTION);
2900 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2901}
2902
2903
2904void Code::set_stack_slots(unsigned slots) {
2905 ASSERT(kind() == OPTIMIZED_FUNCTION);
2906 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2907}
2908
2909
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002910unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002911 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002912 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913}
2914
2915
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002916void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 ASSERT(kind() == OPTIMIZED_FUNCTION);
2918 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002919 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920}
2921
2922
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002923unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002925 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002926}
2927
2928
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002929void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930 ASSERT(kind() == FUNCTION);
2931 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002932 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933}
2934
2935
2936CheckType Code::check_type() {
2937 ASSERT(is_call_stub() || is_keyed_call_stub());
2938 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2939 return static_cast<CheckType>(type);
2940}
2941
2942
2943void Code::set_check_type(CheckType value) {
2944 ASSERT(is_call_stub() || is_keyed_call_stub());
2945 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2946}
2947
2948
danno@chromium.org40cb8782011-05-25 07:58:50 +00002949byte Code::unary_op_type() {
2950 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002951 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2952}
2953
2954
danno@chromium.org40cb8782011-05-25 07:58:50 +00002955void Code::set_unary_op_type(byte value) {
2956 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002957 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2958}
2959
2960
danno@chromium.org40cb8782011-05-25 07:58:50 +00002961byte Code::binary_op_type() {
2962 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2964}
2965
2966
danno@chromium.org40cb8782011-05-25 07:58:50 +00002967void Code::set_binary_op_type(byte value) {
2968 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002969 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2970}
2971
2972
danno@chromium.org40cb8782011-05-25 07:58:50 +00002973byte Code::binary_op_result_type() {
2974 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002975 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2976}
2977
2978
danno@chromium.org40cb8782011-05-25 07:58:50 +00002979void Code::set_binary_op_result_type(byte value) {
2980 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002981 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2982}
2983
2984
2985byte Code::compare_state() {
2986 ASSERT(is_compare_ic_stub());
2987 return READ_BYTE_FIELD(this, kCompareStateOffset);
2988}
2989
2990
2991void Code::set_compare_state(byte value) {
2992 ASSERT(is_compare_ic_stub());
2993 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2994}
2995
2996
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002997byte Code::to_boolean_state() {
2998 ASSERT(is_to_boolean_ic_stub());
2999 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3000}
3001
3002
3003void Code::set_to_boolean_state(byte value) {
3004 ASSERT(is_to_boolean_ic_stub());
3005 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3006}
3007
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003008bool Code::is_inline_cache_stub() {
3009 Kind kind = this->kind();
3010 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3011}
3012
3013
3014Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003015 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00003016 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003017 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003018 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003019 int argc,
3020 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003021 // Extra IC state is only allowed for call IC stubs or for store IC
3022 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003023 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003024 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003025 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003026 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003027 // Compute the bit mask.
3028 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003029 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00003030 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003031 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003032 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003033 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003034 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035 // Cast to flags and validate result before returning it.
3036 Flags result = static_cast<Flags>(bits);
3037 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00003038 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003039 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003040 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003041 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003042 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
3043 return result;
3044}
3045
3046
3047Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3048 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003049 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003050 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003051 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003052 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003053 return ComputeFlags(
3054 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003055}
3056
3057
3058Code::Kind Code::ExtractKindFromFlags(Flags flags) {
3059 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
3060 return static_cast<Kind>(bits);
3061}
3062
3063
kasper.lund7276f142008-07-30 08:49:36 +00003064InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
3065 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003066 return static_cast<InlineCacheState>(bits);
3067}
3068
3069
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003070Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3071 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
3072 return static_cast<ExtraICState>(bits);
3073}
3074
3075
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003076InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
3077 int bits = (flags & kFlagsICInLoopMask);
3078 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3079}
3080
3081
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003082PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3083 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3084 return static_cast<PropertyType>(bits);
3085}
3086
3087
3088int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3089 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3090}
3091
3092
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003093InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3094 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3095 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3096}
3097
3098
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003099Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3100 int bits = flags & ~kFlagsTypeMask;
3101 return static_cast<Flags>(bits);
3102}
3103
3104
ager@chromium.org8bb60582008-12-11 12:02:20 +00003105Code* Code::GetCodeFromTargetAddress(Address address) {
3106 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3107 // GetCodeFromTargetAddress might be called when marking objects during mark
3108 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3109 // Code::cast. Code::cast does not work when the object's map is
3110 // marked.
3111 Code* result = reinterpret_cast<Code*>(code);
3112 return result;
3113}
3114
3115
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003116Isolate* Map::isolate() {
3117 return heap()->isolate();
3118}
3119
3120
3121Heap* Map::heap() {
3122 // NOTE: address() helper is not used to save one instruction.
3123 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3124 ASSERT(heap != NULL);
3125 ASSERT(heap->isolate() == Isolate::Current());
3126 return heap;
3127}
3128
3129
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003130Heap* Code::heap() {
3131 // NOTE: address() helper is not used to save one instruction.
3132 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3133 ASSERT(heap != NULL);
3134 ASSERT(heap->isolate() == Isolate::Current());
3135 return heap;
3136}
3137
3138
3139Isolate* Code::isolate() {
3140 return heap()->isolate();
3141}
3142
3143
3144Heap* JSGlobalPropertyCell::heap() {
3145 // NOTE: address() helper is not used to save one instruction.
3146 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3147 ASSERT(heap != NULL);
3148 ASSERT(heap->isolate() == Isolate::Current());
3149 return heap;
3150}
3151
3152
3153Isolate* JSGlobalPropertyCell::isolate() {
3154 return heap()->isolate();
3155}
3156
3157
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003158Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3159 return HeapObject::
3160 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3161}
3162
3163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003164Object* Map::prototype() {
3165 return READ_FIELD(this, kPrototypeOffset);
3166}
3167
3168
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003169void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003170 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003171 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003172 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003173}
3174
3175
lrn@chromium.org303ada72010-10-27 09:33:13 +00003176MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003177 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003178 Object* obj;
3179 { MaybeObject* maybe_obj = CopyDropTransitions();
3180 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3181 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003182 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003183 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003184 isolate()->counters()->map_to_fast_elements()->Increment();
3185 return new_map;
3186}
3187
3188
3189MaybeObject* Map::GetFastDoubleElementsMap() {
3190 if (has_fast_double_elements()) return this;
3191 Object* obj;
3192 { MaybeObject* maybe_obj = CopyDropTransitions();
3193 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3194 }
3195 Map* new_map = Map::cast(obj);
3196 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3197 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003198 return new_map;
3199}
3200
3201
lrn@chromium.org303ada72010-10-27 09:33:13 +00003202MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003203 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003204 Object* obj;
3205 { MaybeObject* maybe_obj = CopyDropTransitions();
3206 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3207 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003208 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003209 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003210 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003211 return new_map;
3212}
3213
3214
danno@chromium.org40cb8782011-05-25 07:58:50 +00003215DescriptorArray* Map::instance_descriptors() {
3216 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3217 if (object->IsSmi()) {
3218 return HEAP->empty_descriptor_array();
3219 } else {
3220 return DescriptorArray::cast(object);
3221 }
3222}
3223
3224
3225void Map::init_instance_descriptors() {
3226 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3227}
3228
3229
3230void Map::clear_instance_descriptors() {
3231 Object* object = READ_FIELD(this,
3232 kInstanceDescriptorsOrBitField3Offset);
3233 if (!object->IsSmi()) {
3234 WRITE_FIELD(
3235 this,
3236 kInstanceDescriptorsOrBitField3Offset,
3237 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3238 }
3239}
3240
3241
3242void Map::set_instance_descriptors(DescriptorArray* value,
3243 WriteBarrierMode mode) {
3244 Object* object = READ_FIELD(this,
3245 kInstanceDescriptorsOrBitField3Offset);
3246 if (value == isolate()->heap()->empty_descriptor_array()) {
3247 clear_instance_descriptors();
3248 return;
3249 } else {
3250 if (object->IsSmi()) {
3251 value->set_bit_field3_storage(Smi::cast(object)->value());
3252 } else {
3253 value->set_bit_field3_storage(
3254 DescriptorArray::cast(object)->bit_field3_storage());
3255 }
3256 }
3257 ASSERT(!is_shared());
3258 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3259 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3260 this,
3261 kInstanceDescriptorsOrBitField3Offset,
3262 mode);
3263}
3264
3265
3266int Map::bit_field3() {
3267 Object* object = READ_FIELD(this,
3268 kInstanceDescriptorsOrBitField3Offset);
3269 if (object->IsSmi()) {
3270 return Smi::cast(object)->value();
3271 } else {
3272 return DescriptorArray::cast(object)->bit_field3_storage();
3273 }
3274}
3275
3276
3277void Map::set_bit_field3(int value) {
3278 ASSERT(Smi::IsValid(value));
3279 Object* object = READ_FIELD(this,
3280 kInstanceDescriptorsOrBitField3Offset);
3281 if (object->IsSmi()) {
3282 WRITE_FIELD(this,
3283 kInstanceDescriptorsOrBitField3Offset,
3284 Smi::FromInt(value));
3285 } else {
3286 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3287 }
3288}
3289
3290
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003291ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003292ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003293ACCESSORS(Map, constructor, Object, kConstructorOffset)
3294
3295ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3296ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003297ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3298 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003299
3300ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3301ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003302ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003303
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003304ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305
3306ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3307ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3308ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3309ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3310ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3311
3312ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3313ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3314ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3315
3316ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3317ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3318ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3319ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3320ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3321ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3322
3323ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3324ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3325
3326ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3327ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3328
3329ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3330ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3332 kPropertyAccessorsOffset)
3333ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3334 kPrototypeTemplateOffset)
3335ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3336ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3337 kNamedPropertyHandlerOffset)
3338ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3339 kIndexedPropertyHandlerOffset)
3340ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3341 kInstanceTemplateOffset)
3342ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3343ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003344ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3345 kInstanceCallHandlerOffset)
3346ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3347 kAccessCheckInfoOffset)
3348ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3349
3350ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003351ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3352 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003353
3354ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3355ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3356
3357ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3358
3359ACCESSORS(Script, source, Object, kSourceOffset)
3360ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003361ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003362ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3363ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003364ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003365ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003366ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003368ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003369ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003370ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003371ACCESSORS(Script, eval_from_instructions_offset, Smi,
3372 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003373
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003374#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3376ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3377ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3378ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3379
3380ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3381ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3382ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3383ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003384#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003385
3386ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003387ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3388ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003389ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3390 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003391ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3393ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003394ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003395ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3396 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003397
3398BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3399 kHiddenPrototypeBit)
3400BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3401BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3402 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003403BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3404 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3406 kIsExpressionBit)
3407BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3408 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003409BOOL_GETTER(SharedFunctionInfo,
3410 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003411 has_only_simple_this_property_assignments,
3412 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003413BOOL_ACCESSORS(SharedFunctionInfo,
3414 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003415 allows_lazy_compilation,
3416 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003417BOOL_ACCESSORS(SharedFunctionInfo,
3418 compiler_hints,
3419 uses_arguments,
3420 kUsesArguments)
3421BOOL_ACCESSORS(SharedFunctionInfo,
3422 compiler_hints,
3423 has_duplicate_parameters,
3424 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003425
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003426
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003427#if V8_HOST_ARCH_32_BIT
3428SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3429SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003430 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003431SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003432 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003433SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3434SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003435 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003436SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3437SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003439SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003440 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003441SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003442 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003443SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003444#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003445
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003446#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003447 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003448 int holder::name() { \
3449 int value = READ_INT_FIELD(this, offset); \
3450 ASSERT(kHeapObjectTag == 1); \
3451 ASSERT((value & kHeapObjectTag) == 0); \
3452 return value >> 1; \
3453 } \
3454 void holder::set_##name(int value) { \
3455 ASSERT(kHeapObjectTag == 1); \
3456 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3457 (value & 0xC0000000) == 0x000000000); \
3458 WRITE_INT_FIELD(this, \
3459 offset, \
3460 (value << 1) & ~kHeapObjectTag); \
3461 }
3462
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003463#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3464 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003465 INT_ACCESSORS(holder, name, offset)
3466
3467
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003468PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003469PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3470 formal_parameter_count,
3471 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003472
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003473PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3474 expected_nof_properties,
3475 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003476PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3477
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003478PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3479PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3480 start_position_and_type,
3481 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003482
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003483PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3484 function_token_position,
3485 kFunctionTokenPositionOffset)
3486PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3487 compiler_hints,
3488 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003489
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003490PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3491 this_property_assignments_count,
3492 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003493PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003494#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003495
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003496
3497int SharedFunctionInfo::construction_count() {
3498 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3499}
3500
3501
3502void SharedFunctionInfo::set_construction_count(int value) {
3503 ASSERT(0 <= value && value < 256);
3504 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3505}
3506
3507
whesse@chromium.org7b260152011-06-20 15:33:18 +00003508BOOL_ACCESSORS(SharedFunctionInfo,
3509 compiler_hints,
3510 live_objects_may_exist,
3511 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003512
3513
3514bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003515 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003516}
3517
3518
whesse@chromium.org7b260152011-06-20 15:33:18 +00003519BOOL_GETTER(SharedFunctionInfo,
3520 compiler_hints,
3521 optimization_disabled,
3522 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523
3524
3525void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3526 set_compiler_hints(BooleanBit::set(compiler_hints(),
3527 kOptimizationDisabled,
3528 disable));
3529 // If disabling optimizations we reflect that in the code object so
3530 // it will not be counted as optimizable code.
3531 if ((code()->kind() == Code::FUNCTION) && disable) {
3532 code()->set_optimizable(false);
3533 }
3534}
3535
3536
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003537BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003538 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003539BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3540BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3541 name_should_print_as_anonymous,
3542 kNameShouldPrintAsAnonymous)
3543BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3544BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003545
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003546ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3547ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3548
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003549ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3550
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003551bool Script::HasValidSource() {
3552 Object* src = this->source();
3553 if (!src->IsString()) return true;
3554 String* src_str = String::cast(src);
3555 if (!StringShape(src_str).IsExternal()) return true;
3556 if (src_str->IsAsciiRepresentation()) {
3557 return ExternalAsciiString::cast(src)->resource() != NULL;
3558 } else if (src_str->IsTwoByteRepresentation()) {
3559 return ExternalTwoByteString::cast(src)->resource() != NULL;
3560 }
3561 return true;
3562}
3563
3564
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003565void SharedFunctionInfo::DontAdaptArguments() {
3566 ASSERT(code()->kind() == Code::BUILTIN);
3567 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3568}
3569
3570
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003571int SharedFunctionInfo::start_position() {
3572 return start_position_and_type() >> kStartPositionShift;
3573}
3574
3575
3576void SharedFunctionInfo::set_start_position(int start_position) {
3577 set_start_position_and_type((start_position << kStartPositionShift)
3578 | (start_position_and_type() & ~kStartPositionMask));
3579}
3580
3581
3582Code* SharedFunctionInfo::code() {
3583 return Code::cast(READ_FIELD(this, kCodeOffset));
3584}
3585
3586
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003587Code* SharedFunctionInfo::unchecked_code() {
3588 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3589}
3590
3591
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003592void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003593 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003594 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003595}
3596
3597
ager@chromium.orgb5737492010-07-15 09:29:43 +00003598SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3599 return reinterpret_cast<SerializedScopeInfo*>(
3600 READ_FIELD(this, kScopeInfoOffset));
3601}
3602
3603
3604void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3605 WriteBarrierMode mode) {
3606 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003607 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003608}
3609
3610
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003611Smi* SharedFunctionInfo::deopt_counter() {
3612 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3613}
3614
3615
3616void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3617 WRITE_FIELD(this, kDeoptCounterOffset, value);
3618}
3619
3620
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003621bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003622 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003623 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003624}
3625
3626
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003627bool SharedFunctionInfo::IsApiFunction() {
3628 return function_data()->IsFunctionTemplateInfo();
3629}
3630
3631
3632FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3633 ASSERT(IsApiFunction());
3634 return FunctionTemplateInfo::cast(function_data());
3635}
3636
3637
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003638bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003639 return function_data()->IsSmi();
3640}
3641
3642
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003643BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3644 ASSERT(HasBuiltinFunctionId());
3645 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003646}
3647
3648
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003649int SharedFunctionInfo::code_age() {
3650 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3651}
3652
3653
3654void SharedFunctionInfo::set_code_age(int code_age) {
3655 set_compiler_hints(compiler_hints() |
3656 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3657}
3658
3659
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003660bool SharedFunctionInfo::has_deoptimization_support() {
3661 Code* code = this->code();
3662 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3663}
3664
3665
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003666bool JSFunction::IsBuiltin() {
3667 return context()->global()->IsJSBuiltinsObject();
3668}
3669
3670
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003671bool JSFunction::NeedsArgumentsAdaption() {
3672 return shared()->formal_parameter_count() !=
3673 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3674}
3675
3676
3677bool JSFunction::IsOptimized() {
3678 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3679}
3680
3681
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003682bool JSFunction::IsOptimizable() {
3683 return code()->kind() == Code::FUNCTION && code()->optimizable();
3684}
3685
3686
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003687bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003688 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003689}
3690
3691
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003692Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003693 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694}
3695
3696
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003697Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003698 return reinterpret_cast<Code*>(
3699 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003700}
3701
3702
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003703void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003704 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003705 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003706 Address entry = value->entry();
3707 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708}
3709
3710
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003711void JSFunction::ReplaceCode(Code* code) {
3712 bool was_optimized = IsOptimized();
3713 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3714
3715 set_code(code);
3716
3717 // Add/remove the function from the list of optimized functions for this
3718 // context based on the state change.
3719 if (!was_optimized && is_optimized) {
3720 context()->global_context()->AddOptimizedFunction(this);
3721 }
3722 if (was_optimized && !is_optimized) {
3723 context()->global_context()->RemoveOptimizedFunction(this);
3724 }
3725}
3726
3727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003728Context* JSFunction::context() {
3729 return Context::cast(READ_FIELD(this, kContextOffset));
3730}
3731
3732
3733Object* JSFunction::unchecked_context() {
3734 return READ_FIELD(this, kContextOffset);
3735}
3736
3737
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003738SharedFunctionInfo* JSFunction::unchecked_shared() {
3739 return reinterpret_cast<SharedFunctionInfo*>(
3740 READ_FIELD(this, kSharedFunctionInfoOffset));
3741}
3742
3743
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003744void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003745 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746 WRITE_FIELD(this, kContextOffset, value);
3747 WRITE_BARRIER(this, kContextOffset);
3748}
3749
3750ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3751 kPrototypeOrInitialMapOffset)
3752
3753
3754Map* JSFunction::initial_map() {
3755 return Map::cast(prototype_or_initial_map());
3756}
3757
3758
3759void JSFunction::set_initial_map(Map* value) {
3760 set_prototype_or_initial_map(value);
3761}
3762
3763
3764bool JSFunction::has_initial_map() {
3765 return prototype_or_initial_map()->IsMap();
3766}
3767
3768
3769bool JSFunction::has_instance_prototype() {
3770 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3771}
3772
3773
3774bool JSFunction::has_prototype() {
3775 return map()->has_non_instance_prototype() || has_instance_prototype();
3776}
3777
3778
3779Object* JSFunction::instance_prototype() {
3780 ASSERT(has_instance_prototype());
3781 if (has_initial_map()) return initial_map()->prototype();
3782 // When there is no initial map and the prototype is a JSObject, the
3783 // initial map field is used for the prototype field.
3784 return prototype_or_initial_map();
3785}
3786
3787
3788Object* JSFunction::prototype() {
3789 ASSERT(has_prototype());
3790 // If the function's prototype property has been set to a non-JSObject
3791 // value, that value is stored in the constructor field of the map.
3792 if (map()->has_non_instance_prototype()) return map()->constructor();
3793 return instance_prototype();
3794}
3795
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003796bool JSFunction::should_have_prototype() {
3797 return map()->function_with_prototype();
3798}
3799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003800
3801bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003802 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003803}
3804
3805
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003806int JSFunction::NumberOfLiterals() {
3807 return literals()->length();
3808}
3809
3810
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003811Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003812 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003813 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003814}
3815
3816
3817void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3818 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003819 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003820 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3821 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3822}
3823
3824
3825Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003826 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003827 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3828}
3829
3830
3831void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3832 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003833 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003834 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003835 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003836}
3837
3838
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003839ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003840ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003841
3842
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003843ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3844ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3845
3846
3847ObjectHashTable* JSWeakMap::unchecked_table() {
3848 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3849}
3850
3851
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003852Address Foreign::address() {
3853 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003854}
3855
3856
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003857void Foreign::set_address(Address value) {
3858 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003859}
3860
3861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003862ACCESSORS(JSValue, value, Object, kValueOffset)
3863
3864
3865JSValue* JSValue::cast(Object* obj) {
3866 ASSERT(obj->IsJSValue());
3867 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3868 return reinterpret_cast<JSValue*>(obj);
3869}
3870
3871
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003872ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3873ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3874ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3875ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3876ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3877SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3878SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3879
3880
3881JSMessageObject* JSMessageObject::cast(Object* obj) {
3882 ASSERT(obj->IsJSMessageObject());
3883 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3884 return reinterpret_cast<JSMessageObject*>(obj);
3885}
3886
3887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003888INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003889ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003890ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003891ACCESSORS(Code, next_code_flushing_candidate,
3892 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893
3894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895byte* Code::instruction_start() {
3896 return FIELD_ADDR(this, kHeaderSize);
3897}
3898
3899
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003900byte* Code::instruction_end() {
3901 return instruction_start() + instruction_size();
3902}
3903
3904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003905int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003906 return RoundUp(instruction_size(), kObjectAlignment);
3907}
3908
3909
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910FixedArray* Code::unchecked_deoptimization_data() {
3911 return reinterpret_cast<FixedArray*>(
3912 READ_FIELD(this, kDeoptimizationDataOffset));
3913}
3914
3915
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003916ByteArray* Code::unchecked_relocation_info() {
3917 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003918}
3919
3920
3921byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003922 return unchecked_relocation_info()->GetDataStartAddress();
3923}
3924
3925
3926int Code::relocation_size() {
3927 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003928}
3929
3930
3931byte* Code::entry() {
3932 return instruction_start();
3933}
3934
3935
3936bool Code::contains(byte* pc) {
3937 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003938 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003939}
3940
3941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003942ACCESSORS(JSArray, length, Object, kLengthOffset)
3943
3944
ager@chromium.org236ad962008-09-25 09:45:57 +00003945ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003946
3947
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003948JSRegExp::Type JSRegExp::TypeTag() {
3949 Object* data = this->data();
3950 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3951 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3952 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003953}
3954
3955
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003956JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3957 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3958 return static_cast<JSRegExp::Type>(smi->value());
3959}
3960
3961
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003962int JSRegExp::CaptureCount() {
3963 switch (TypeTag()) {
3964 case ATOM:
3965 return 0;
3966 case IRREGEXP:
3967 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3968 default:
3969 UNREACHABLE();
3970 return -1;
3971 }
3972}
3973
3974
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003975JSRegExp::Flags JSRegExp::GetFlags() {
3976 ASSERT(this->data()->IsFixedArray());
3977 Object* data = this->data();
3978 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3979 return Flags(smi->value());
3980}
3981
3982
3983String* JSRegExp::Pattern() {
3984 ASSERT(this->data()->IsFixedArray());
3985 Object* data = this->data();
3986 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3987 return pattern;
3988}
3989
3990
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003991Object* JSRegExp::DataAt(int index) {
3992 ASSERT(TypeTag() != NOT_COMPILED);
3993 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003994}
3995
3996
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003997Object* JSRegExp::DataAtUnchecked(int index) {
3998 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3999 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4000 return READ_FIELD(fa, offset);
4001}
4002
4003
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004004void JSRegExp::SetDataAt(int index, Object* value) {
4005 ASSERT(TypeTag() != NOT_COMPILED);
4006 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4007 FixedArray::cast(data())->set(index, value);
4008}
4009
4010
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004011void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4012 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4013 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4014 if (value->IsSmi()) {
4015 fa->set_unchecked(index, Smi::cast(value));
4016 } else {
4017 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4018 }
4019}
4020
4021
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004022JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004023 ElementsKind kind = map()->elements_kind();
4024 ASSERT((kind == FAST_ELEMENTS &&
4025 (elements()->map() == GetHeap()->fixed_array_map() ||
4026 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004027 (kind == FAST_DOUBLE_ELEMENTS &&
4028 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004029 (kind == DICTIONARY_ELEMENTS &&
4030 elements()->IsFixedArray() &&
4031 elements()->IsDictionary()) ||
4032 (kind > DICTIONARY_ELEMENTS));
4033 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004034}
4035
4036
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004037ElementsAccessor* JSObject::GetElementsAccessor() {
4038 return ElementsAccessor::ForKind(GetElementsKind());
4039}
4040
4041
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004042bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004043 return GetElementsKind() == FAST_ELEMENTS;
4044}
4045
4046
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004047bool JSObject::HasFastDoubleElements() {
4048 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4049}
4050
4051
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004052bool JSObject::HasDictionaryElements() {
4053 return GetElementsKind() == DICTIONARY_ELEMENTS;
4054}
4055
4056
ager@chromium.org3811b432009-10-28 14:53:37 +00004057bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004058 HeapObject* array = elements();
4059 ASSERT(array != NULL);
4060 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004061}
4062
4063
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004064#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4065bool JSObject::HasExternal##name##Elements() { \
4066 HeapObject* array = elements(); \
4067 ASSERT(array != NULL); \
4068 if (!array->IsHeapObject()) \
4069 return false; \
4070 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004071}
4072
4073
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004074EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4075EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4076EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4077EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4078 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4079EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4080EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4081 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4082EXTERNAL_ELEMENTS_CHECK(Float,
4083 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004084EXTERNAL_ELEMENTS_CHECK(Double,
4085 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004086EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004087
4088
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004089bool JSObject::HasNamedInterceptor() {
4090 return map()->has_named_interceptor();
4091}
4092
4093
4094bool JSObject::HasIndexedInterceptor() {
4095 return map()->has_indexed_interceptor();
4096}
4097
4098
ager@chromium.org5c838252010-02-19 08:53:10 +00004099bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004100 bool result = elements()->IsFixedArray() ||
4101 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004102 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004103 return result;
4104}
4105
4106
lrn@chromium.org303ada72010-10-27 09:33:13 +00004107MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004108 ASSERT(HasFastElements());
4109 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004110 Isolate* isolate = GetIsolate();
4111 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004112 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004113 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4114 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004115 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4116 return maybe_writable_elems;
4117 }
4118 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004119 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004120 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004121 return writable_elems;
4122}
4123
4124
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004125StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004126 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004127 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004128}
4129
4130
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004131NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004132 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004133 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004134}
4135
4136
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004137bool String::IsHashFieldComputed(uint32_t field) {
4138 return (field & kHashNotComputedMask) == 0;
4139}
4140
4141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004142bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004143 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004144}
4145
4146
4147uint32_t String::Hash() {
4148 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004149 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004150 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004151 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004152 return ComputeAndSetHash();
4153}
4154
4155
ager@chromium.org7c537e22008-10-16 08:43:32 +00004156StringHasher::StringHasher(int length)
4157 : length_(length),
4158 raw_running_hash_(0),
4159 array_index_(0),
4160 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4161 is_first_char_(true),
4162 is_valid_(true) { }
4163
4164
4165bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004166 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004167}
4168
4169
4170void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004171 // Use the Jenkins one-at-a-time hash function to update the hash
4172 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004173 raw_running_hash_ += c;
4174 raw_running_hash_ += (raw_running_hash_ << 10);
4175 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004176 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004177 if (is_array_index_) {
4178 if (c < '0' || c > '9') {
4179 is_array_index_ = false;
4180 } else {
4181 int d = c - '0';
4182 if (is_first_char_) {
4183 is_first_char_ = false;
4184 if (c == '0' && length_ > 1) {
4185 is_array_index_ = false;
4186 return;
4187 }
4188 }
4189 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4190 is_array_index_ = false;
4191 } else {
4192 array_index_ = array_index_ * 10 + d;
4193 }
4194 }
4195 }
4196}
4197
4198
4199void StringHasher::AddCharacterNoIndex(uc32 c) {
4200 ASSERT(!is_array_index());
4201 raw_running_hash_ += c;
4202 raw_running_hash_ += (raw_running_hash_ << 10);
4203 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4204}
4205
4206
4207uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004208 // Get the calculated raw hash value and do some more bit ops to distribute
4209 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004210 uint32_t result = raw_running_hash_;
4211 result += (result << 3);
4212 result ^= (result >> 11);
4213 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004214 if (result == 0) {
4215 result = 27;
4216 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004217 return result;
4218}
4219
4220
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004221template <typename schar>
4222uint32_t HashSequentialString(const schar* chars, int length) {
4223 StringHasher hasher(length);
4224 if (!hasher.has_trivial_hash()) {
4225 int i;
4226 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4227 hasher.AddCharacter(chars[i]);
4228 }
4229 for (; i < length; i++) {
4230 hasher.AddCharacterNoIndex(chars[i]);
4231 }
4232 }
4233 return hasher.GetHashField();
4234}
4235
4236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004237bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004238 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004239 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4240 return false;
4241 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004242 return SlowAsArrayIndex(index);
4243}
4244
4245
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004246Object* JSReceiver::GetPrototype() {
4247 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004248}
4249
4250
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004251bool JSReceiver::HasProperty(String* name) {
4252 if (IsJSProxy()) {
4253 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4254 }
4255 return GetPropertyAttribute(name) != ABSENT;
4256}
4257
4258
4259bool JSReceiver::HasLocalProperty(String* name) {
4260 if (IsJSProxy()) {
4261 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4262 }
4263 return GetLocalPropertyAttribute(name) != ABSENT;
4264}
4265
4266
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004267PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004268 return GetPropertyAttributeWithReceiver(this, key);
4269}
4270
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004271// TODO(504): this may be useful in other places too where JSGlobalProxy
4272// is used.
4273Object* JSObject::BypassGlobalProxy() {
4274 if (IsJSGlobalProxy()) {
4275 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004276 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004277 ASSERT(proto->IsJSGlobalObject());
4278 return proto;
4279 }
4280 return this;
4281}
4282
4283
4284bool JSObject::HasHiddenPropertiesObject() {
4285 ASSERT(!IsJSGlobalProxy());
4286 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004287 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004288 false) != ABSENT;
4289}
4290
4291
4292Object* JSObject::GetHiddenPropertiesObject() {
4293 ASSERT(!IsJSGlobalProxy());
4294 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004295 // You can't install a getter on a property indexed by the hidden symbol,
4296 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4297 // object.
4298 Object* result =
4299 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004300 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004301 &attributes)->ToObjectUnchecked();
4302 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004303}
4304
4305
lrn@chromium.org303ada72010-10-27 09:33:13 +00004306MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004307 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004308 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004309 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004310 DONT_ENUM,
4311 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004312}
4313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004314
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004315bool JSObject::HasHiddenProperties() {
4316 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4317}
4318
4319
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320bool JSObject::HasElement(uint32_t index) {
4321 return HasElementWithReceiver(this, index);
4322}
4323
4324
4325bool AccessorInfo::all_can_read() {
4326 return BooleanBit::get(flag(), kAllCanReadBit);
4327}
4328
4329
4330void AccessorInfo::set_all_can_read(bool value) {
4331 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4332}
4333
4334
4335bool AccessorInfo::all_can_write() {
4336 return BooleanBit::get(flag(), kAllCanWriteBit);
4337}
4338
4339
4340void AccessorInfo::set_all_can_write(bool value) {
4341 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4342}
4343
4344
ager@chromium.org870a0b62008-11-04 11:43:05 +00004345bool AccessorInfo::prohibits_overwriting() {
4346 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4347}
4348
4349
4350void AccessorInfo::set_prohibits_overwriting(bool value) {
4351 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4352}
4353
4354
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004355PropertyAttributes AccessorInfo::property_attributes() {
4356 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4357}
4358
4359
4360void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4361 ASSERT(AttributesField::is_valid(attributes));
4362 int rest_value = flag()->value() & ~AttributesField::mask();
4363 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4364}
4365
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004366
4367template<typename Shape, typename Key>
4368void Dictionary<Shape, Key>::SetEntry(int entry,
4369 Object* key,
4370 Object* value) {
4371 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4372}
4373
4374
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004375template<typename Shape, typename Key>
4376void Dictionary<Shape, Key>::SetEntry(int entry,
4377 Object* key,
4378 Object* value,
4379 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004380 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004381 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004382 AssertNoAllocation no_gc;
4383 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004384 FixedArray::set(index, key, mode);
4385 FixedArray::set(index+1, value, mode);
4386 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004387}
4388
4389
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004390bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4391 ASSERT(other->IsNumber());
4392 return key == static_cast<uint32_t>(other->Number());
4393}
4394
4395
4396uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4397 return ComputeIntegerHash(key);
4398}
4399
4400
4401uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4402 ASSERT(other->IsNumber());
4403 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4404}
4405
4406
4407MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4408 return Isolate::Current()->heap()->NumberFromUint32(key);
4409}
4410
4411
4412bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4413 // We know that all entries in a hash table had their hash keys created.
4414 // Use that knowledge to have fast failure.
4415 if (key->Hash() != String::cast(other)->Hash()) return false;
4416 return key->Equals(String::cast(other));
4417}
4418
4419
4420uint32_t StringDictionaryShape::Hash(String* key) {
4421 return key->Hash();
4422}
4423
4424
4425uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4426 return String::cast(other)->Hash();
4427}
4428
4429
4430MaybeObject* StringDictionaryShape::AsObject(String* key) {
4431 return key;
4432}
4433
4434
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004435bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4436 return key == JSObject::cast(other);
4437}
4438
4439
4440uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4441 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4442 ASSERT(!maybe_hash->IsFailure());
4443 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4444}
4445
4446
4447uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4448 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4449 JSObject::OMIT_CREATION);
4450 ASSERT(!maybe_hash->IsFailure());
4451 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4452}
4453
4454
4455MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4456 return key;
4457}
4458
4459
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004460void ObjectHashTable::RemoveEntry(int entry) {
4461 RemoveEntry(entry, GetHeap());
4462}
4463
4464
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004465void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004466 // No write barrier is needed since empty_fixed_array is not in new space.
4467 // Please note this function is used during marking:
4468 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004469 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4470 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004471}
4472
4473
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004474void JSArray::EnsureSize(int required_size) {
4475 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004476 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004477 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4478 if (elts->length() < required_size) {
4479 // Doubling in size would be overkill, but leave some slack to avoid
4480 // constantly growing.
4481 Expand(required_size + (required_size >> 3));
4482 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004483 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004484 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4485 // Expand will allocate a new backing store in new space even if the size
4486 // we asked for isn't larger than what we had before.
4487 Expand(required_size);
4488 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004489}
4490
4491
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004492void JSArray::set_length(Smi* length) {
4493 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4494}
4495
4496
ager@chromium.org7c537e22008-10-16 08:43:32 +00004497void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004498 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004499 set_elements(storage);
4500}
4501
4502
lrn@chromium.org303ada72010-10-27 09:33:13 +00004503MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004504 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004505 return GetHeap()->CopyFixedArray(this);
4506}
4507
4508
4509Relocatable::Relocatable(Isolate* isolate) {
4510 ASSERT(isolate == Isolate::Current());
4511 isolate_ = isolate;
4512 prev_ = isolate->relocatable_top();
4513 isolate->set_relocatable_top(this);
4514}
4515
4516
4517Relocatable::~Relocatable() {
4518 ASSERT(isolate_ == Isolate::Current());
4519 ASSERT_EQ(isolate_->relocatable_top(), this);
4520 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004521}
4522
4523
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004524int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4525 return map->instance_size();
4526}
4527
4528
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004529void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004530 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004531 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004532}
4533
4534
4535template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004536void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004537 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004538 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004539}
4540
4541
4542void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4543 typedef v8::String::ExternalAsciiStringResource Resource;
4544 v->VisitExternalAsciiString(
4545 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4546}
4547
4548
4549template<typename StaticVisitor>
4550void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4551 typedef v8::String::ExternalAsciiStringResource Resource;
4552 StaticVisitor::VisitExternalAsciiString(
4553 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4554}
4555
4556
4557void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4558 typedef v8::String::ExternalStringResource Resource;
4559 v->VisitExternalTwoByteString(
4560 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4561}
4562
4563
4564template<typename StaticVisitor>
4565void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4566 typedef v8::String::ExternalStringResource Resource;
4567 StaticVisitor::VisitExternalTwoByteString(
4568 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4569}
4570
4571#define SLOT_ADDR(obj, offset) \
4572 reinterpret_cast<Object**>((obj)->address() + offset)
4573
4574template<int start_offset, int end_offset, int size>
4575void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4576 HeapObject* obj,
4577 ObjectVisitor* v) {
4578 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4579}
4580
4581
4582template<int start_offset>
4583void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4584 int object_size,
4585 ObjectVisitor* v) {
4586 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4587}
4588
4589#undef SLOT_ADDR
4590
4591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004592#undef CAST_ACCESSOR
4593#undef INT_ACCESSORS
4594#undef SMI_ACCESSORS
4595#undef ACCESSORS
4596#undef FIELD_ADDR
4597#undef READ_FIELD
4598#undef WRITE_FIELD
4599#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004600#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004601#undef READ_MEMADDR_FIELD
4602#undef WRITE_MEMADDR_FIELD
4603#undef READ_DOUBLE_FIELD
4604#undef WRITE_DOUBLE_FIELD
4605#undef READ_INT_FIELD
4606#undef WRITE_INT_FIELD
4607#undef READ_SHORT_FIELD
4608#undef WRITE_SHORT_FIELD
4609#undef READ_BYTE_FIELD
4610#undef WRITE_BYTE_FIELD
4611
4612
4613} } // namespace v8::internal
4614
4615#endif // V8_OBJECTS_INL_H_