blob: c5fda89e42efdf368c5300de5ef34ef7b19e4009 [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() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000555 map == heap->global_context_map() ||
556 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000557 }
558 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
562bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000563 return Object::IsHeapObject() &&
564 HeapObject::cast(this)->map() ==
565 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566}
567
568
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000569bool Object::IsSerializedScopeInfo() {
570 return Object::IsHeapObject() &&
571 HeapObject::cast(this)->map() ==
572 HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
573}
574
575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576bool Object::IsJSFunction() {
577 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000578 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000579}
580
581
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000582template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583 return obj->IsJSFunction();
584}
585
586
587bool Object::IsCode() {
588 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000589 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000590}
591
592
593bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000594 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595 return Object::IsHeapObject()
596 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
597}
598
599
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000600bool Object::IsJSGlobalPropertyCell() {
601 return Object::IsHeapObject()
602 && HeapObject::cast(this)->map()->instance_type()
603 == JS_GLOBAL_PROPERTY_CELL_TYPE;
604}
605
606
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607bool Object::IsSharedFunctionInfo() {
608 return Object::IsHeapObject() &&
609 (HeapObject::cast(this)->map()->instance_type() ==
610 SHARED_FUNCTION_INFO_TYPE);
611}
612
613
614bool Object::IsJSValue() {
615 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000616 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
617}
618
619
620bool Object::IsJSMessageObject() {
621 return Object::IsHeapObject()
622 && (HeapObject::cast(this)->map()->instance_type() ==
623 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624}
625
626
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000627bool Object::IsStringWrapper() {
628 return IsJSValue() && JSValue::cast(this)->value()->IsString();
629}
630
631
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000632bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000634 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000635}
636
637
638bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000639 return IsOddball() &&
640 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
644bool Object::IsJSArray() {
645 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000646 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000647}
648
649
ager@chromium.org236ad962008-09-25 09:45:57 +0000650bool Object::IsJSRegExp() {
651 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000652 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000653}
654
655
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000656template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657 return obj->IsJSArray();
658}
659
660
661bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000662 return Object::IsHeapObject() &&
663 HeapObject::cast(this)->map() ==
664 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665}
666
667
668bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000669 return IsHashTable() &&
670 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671}
672
673
674bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000675 return IsHashTable() && this ==
676 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000677}
678
679
ager@chromium.orgac091b72010-05-05 07:34:42 +0000680bool Object::IsJSFunctionResultCache() {
681 if (!IsFixedArray()) return false;
682 FixedArray* self = FixedArray::cast(this);
683 int length = self->length();
684 if (length < JSFunctionResultCache::kEntriesIndex) return false;
685 if ((length - JSFunctionResultCache::kEntriesIndex)
686 % JSFunctionResultCache::kEntrySize != 0) {
687 return false;
688 }
689#ifdef DEBUG
690 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
691#endif
692 return true;
693}
694
695
ricow@chromium.org65fae842010-08-25 15:26:24 +0000696bool Object::IsNormalizedMapCache() {
697 if (!IsFixedArray()) return false;
698 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
699 return false;
700 }
701#ifdef DEBUG
702 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
703#endif
704 return true;
705}
706
707
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000708bool Object::IsCompilationCacheTable() {
709 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000710}
711
712
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000713bool Object::IsCodeCacheHashTable() {
714 return IsHashTable();
715}
716
717
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000718bool Object::IsPolymorphicCodeCacheHashTable() {
719 return IsHashTable();
720}
721
722
ager@chromium.org236ad962008-09-25 09:45:57 +0000723bool Object::IsMapCache() {
724 return IsHashTable();
725}
726
727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728bool Object::IsPrimitive() {
729 return IsOddball() || IsNumber() || IsString();
730}
731
732
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000733bool Object::IsJSGlobalProxy() {
734 bool result = IsHeapObject() &&
735 (HeapObject::cast(this)->map()->instance_type() ==
736 JS_GLOBAL_PROXY_TYPE);
737 ASSERT(!result || IsAccessCheckNeeded());
738 return result;
739}
740
741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000743 if (!IsHeapObject()) return false;
744
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000745 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000746 return type == JS_GLOBAL_OBJECT_TYPE ||
747 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748}
749
750
751bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752 return IsHeapObject() &&
753 (HeapObject::cast(this)->map()->instance_type() ==
754 JS_GLOBAL_OBJECT_TYPE);
755}
756
757
758bool Object::IsJSBuiltinsObject() {
759 return IsHeapObject() &&
760 (HeapObject::cast(this)->map()->instance_type() ==
761 JS_BUILTINS_OBJECT_TYPE);
762}
763
764
765bool Object::IsUndetectableObject() {
766 return IsHeapObject()
767 && HeapObject::cast(this)->map()->is_undetectable();
768}
769
770
771bool Object::IsAccessCheckNeeded() {
772 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000773 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774}
775
776
777bool Object::IsStruct() {
778 if (!IsHeapObject()) return false;
779 switch (HeapObject::cast(this)->map()->instance_type()) {
780#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
781 STRUCT_LIST(MAKE_STRUCT_CASE)
782#undef MAKE_STRUCT_CASE
783 default: return false;
784 }
785}
786
787
788#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
789 bool Object::Is##Name() { \
790 return Object::IsHeapObject() \
791 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
792 }
793 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
794#undef MAKE_STRUCT_PREDICATE
795
796
797bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000802bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
804}
805
806
807bool Object::IsTheHole() {
808 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
812bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000813 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814}
815
816
817bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000818 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819}
820
821
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000822bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000823 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000824}
825
826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000827double Object::Number() {
828 ASSERT(IsNumber());
829 return IsSmi()
830 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
831 : reinterpret_cast<HeapNumber*>(this)->value();
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 if (IsSmi()) return this;
837 if (IsHeapNumber()) {
838 double value = HeapNumber::cast(this)->value();
839 int int_value = FastD2I(value);
840 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
841 return Smi::FromInt(int_value);
842 }
843 }
844 return Failure::Exception();
845}
846
847
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000848bool Object::HasSpecificClassOf(String* name) {
849 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
850}
851
852
lrn@chromium.org303ada72010-10-27 09:33:13 +0000853MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000854 // GetElement can trigger a getter which can cause allocation.
855 // This was not always the case. This ASSERT is here to catch
856 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000857 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000858 return GetElementWithReceiver(this, index);
859}
860
861
lrn@chromium.org303ada72010-10-27 09:33:13 +0000862Object* Object::GetElementNoExceptionThrown(uint32_t index) {
863 MaybeObject* maybe = GetElementWithReceiver(this, index);
864 ASSERT(!maybe->IsFailure());
865 Object* result = NULL; // Initialization to please compiler.
866 maybe->ToObject(&result);
867 return result;
868}
869
870
871MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000872 PropertyAttributes attributes;
873 return GetPropertyWithReceiver(this, key, &attributes);
874}
875
876
lrn@chromium.org303ada72010-10-27 09:33:13 +0000877MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000878 return GetPropertyWithReceiver(this, key, attributes);
879}
880
881
882#define FIELD_ADDR(p, offset) \
883 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
884
885#define READ_FIELD(p, offset) \
886 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
887
888#define WRITE_FIELD(p, offset, value) \
889 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
890
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000893 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000894
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000895// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000896// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000897#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000898 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000899 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000900 } else { \
901 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000902 ASSERT(heap->InNewSpace(object) || \
903 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000904 Page::FromAddress(object->address())-> \
905 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000906 }
907
lrn@chromium.org7516f052011-03-30 08:52:27 +0000908#ifndef V8_TARGET_ARCH_MIPS
909 #define READ_DOUBLE_FIELD(p, offset) \
910 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
911#else // V8_TARGET_ARCH_MIPS
912 // Prevent gcc from using load-double (mips ldc1) on (possibly)
913 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000914 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000915 union conversion {
916 double d;
917 uint32_t u[2];
918 } c;
919 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
920 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
921 return c.d;
922 }
923 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
924#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925
lrn@chromium.org7516f052011-03-30 08:52:27 +0000926
927#ifndef V8_TARGET_ARCH_MIPS
928 #define WRITE_DOUBLE_FIELD(p, offset, value) \
929 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
930#else // V8_TARGET_ARCH_MIPS
931 // Prevent gcc from using store-double (mips sdc1) on (possibly)
932 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000933 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000934 double value) {
935 union conversion {
936 double d;
937 uint32_t u[2];
938 } c;
939 c.d = value;
940 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
941 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
942 }
943 #define WRITE_DOUBLE_FIELD(p, offset, value) \
944 write_double_field(p, offset, value)
945#endif // V8_TARGET_ARCH_MIPS
946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000947
948#define READ_INT_FIELD(p, offset) \
949 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
950
951#define WRITE_INT_FIELD(p, offset, value) \
952 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
953
ager@chromium.org3e875802009-06-29 08:26:34 +0000954#define READ_INTPTR_FIELD(p, offset) \
955 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
956
957#define WRITE_INTPTR_FIELD(p, offset, value) \
958 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
959
ager@chromium.org7c537e22008-10-16 08:43:32 +0000960#define READ_UINT32_FIELD(p, offset) \
961 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
962
963#define WRITE_UINT32_FIELD(p, offset, value) \
964 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966#define READ_SHORT_FIELD(p, offset) \
967 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
968
969#define WRITE_SHORT_FIELD(p, offset, value) \
970 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
971
972#define READ_BYTE_FIELD(p, offset) \
973 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
974
975#define WRITE_BYTE_FIELD(p, offset, value) \
976 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
977
978
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000979Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
980 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981}
982
983
984int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000985 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986}
987
988
989Smi* Smi::FromInt(int value) {
990 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000991 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000992 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000993 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000994 return reinterpret_cast<Smi*>(tagged_value);
995}
996
997
998Smi* Smi::FromIntptr(intptr_t value) {
999 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001000 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1001 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001002}
1003
1004
1005Failure::Type Failure::type() const {
1006 return static_cast<Type>(value() & kFailureTypeTagMask);
1007}
1008
1009
1010bool Failure::IsInternalError() const {
1011 return type() == INTERNAL_ERROR;
1012}
1013
1014
1015bool Failure::IsOutOfMemoryException() const {
1016 return type() == OUT_OF_MEMORY_EXCEPTION;
1017}
1018
1019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020AllocationSpace Failure::allocation_space() const {
1021 ASSERT_EQ(RETRY_AFTER_GC, type());
1022 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1023 & kSpaceTagMask);
1024}
1025
1026
1027Failure* Failure::InternalError() {
1028 return Construct(INTERNAL_ERROR);
1029}
1030
1031
1032Failure* Failure::Exception() {
1033 return Construct(EXCEPTION);
1034}
1035
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037Failure* Failure::OutOfMemoryException() {
1038 return Construct(OUT_OF_MEMORY_EXCEPTION);
1039}
1040
1041
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001042intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001043 return static_cast<intptr_t>(
1044 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045}
1046
1047
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001048Failure* Failure::RetryAfterGC() {
1049 return RetryAfterGC(NEW_SPACE);
1050}
1051
1052
1053Failure* Failure::RetryAfterGC(AllocationSpace space) {
1054 ASSERT((space & ~kSpaceTagMask) == 0);
1055 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001056}
1057
1058
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001059Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001060 uintptr_t info =
1061 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001062 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001063 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001064}
1065
1066
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001067bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001068#ifdef DEBUG
1069 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1070#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001071
1072#ifdef V8_TARGET_ARCH_X64
1073 // To be representable as a long smi, the value must be a 32-bit integer.
1074 bool result = (value == static_cast<int32_t>(value));
1075#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001076 // To be representable as an tagged small integer, the two
1077 // most-significant bits of 'value' must be either 00 or 11 due to
1078 // sign-extension. To check this we add 01 to the two
1079 // most-significant bits, and check if the most-significant bit is 0
1080 //
1081 // CAUTION: The original code below:
1082 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1083 // may lead to incorrect results according to the C language spec, and
1084 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1085 // compiler may produce undefined results in case of signed integer
1086 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001087 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001088#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001089 ASSERT(result == in_range);
1090 return result;
1091}
1092
1093
kasper.lund7276f142008-07-30 08:49:36 +00001094MapWord MapWord::FromMap(Map* map) {
1095 return MapWord(reinterpret_cast<uintptr_t>(map));
1096}
1097
1098
1099Map* MapWord::ToMap() {
1100 return reinterpret_cast<Map*>(value_);
1101}
1102
1103
1104bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001105 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001106}
1107
1108
1109MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001110 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1111 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001112}
1113
1114
1115HeapObject* MapWord::ToForwardingAddress() {
1116 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001117 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001118}
1119
1120
1121bool MapWord::IsMarked() {
1122 return (value_ & kMarkingMask) == 0;
1123}
1124
1125
1126void MapWord::SetMark() {
1127 value_ &= ~kMarkingMask;
1128}
1129
1130
1131void MapWord::ClearMark() {
1132 value_ |= kMarkingMask;
1133}
1134
1135
1136bool MapWord::IsOverflowed() {
1137 return (value_ & kOverflowMask) != 0;
1138}
1139
1140
1141void MapWord::SetOverflow() {
1142 value_ |= kOverflowMask;
1143}
1144
1145
1146void MapWord::ClearOverflow() {
1147 value_ &= ~kOverflowMask;
1148}
1149
1150
1151MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1152 // Offset is the distance in live bytes from the first live object in the
1153 // same page. The offset between two objects in the same page should not
1154 // exceed the object area size of a page.
1155 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1156
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001157 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001158 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1159
1160 Page* map_page = Page::FromAddress(map_address);
1161 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1162
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001163 uintptr_t map_page_offset =
1164 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001165
1166 uintptr_t encoding =
1167 (compact_offset << kForwardingOffsetShift) |
1168 (map_page_offset << kMapPageOffsetShift) |
1169 (map_page->mc_page_index << kMapPageIndexShift);
1170 return MapWord(encoding);
1171}
1172
1173
1174Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001175 int map_page_index =
1176 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001177 ASSERT_MAP_PAGE_INDEX(map_page_index);
1178
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001179 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001180 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1181 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001182
1183 return (map_space->PageAddress(map_page_index) + map_page_offset);
1184}
1185
1186
1187int MapWord::DecodeOffset() {
1188 // The offset field is represented in the kForwardingOffsetBits
1189 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001190 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1191 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1192 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001193}
1194
1195
1196MapWord MapWord::FromEncodedAddress(Address address) {
1197 return MapWord(reinterpret_cast<uintptr_t>(address));
1198}
1199
1200
1201Address MapWord::ToEncodedAddress() {
1202 return reinterpret_cast<Address>(value_);
1203}
1204
1205
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001206#ifdef DEBUG
1207void HeapObject::VerifyObjectField(int offset) {
1208 VerifyPointer(READ_FIELD(this, offset));
1209}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001210
1211void HeapObject::VerifySmiField(int offset) {
1212 ASSERT(READ_FIELD(this, offset)->IsSmi());
1213}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001214#endif
1215
1216
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001217Heap* HeapObject::GetHeap() {
1218 // During GC, the map pointer in HeapObject is used in various ways that
1219 // prevent us from retrieving Heap from the map.
1220 // Assert that we are not in GC, implement GC code in a way that it doesn't
1221 // pull heap from the map.
1222 ASSERT(HEAP->is_safe_to_read_maps());
1223 return map()->heap();
1224}
1225
1226
1227Isolate* HeapObject::GetIsolate() {
1228 return GetHeap()->isolate();
1229}
1230
1231
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001232Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001233 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234}
1235
1236
1237void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001238 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239}
1240
1241
kasper.lund7276f142008-07-30 08:49:36 +00001242MapWord HeapObject::map_word() {
1243 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1244}
1245
1246
1247void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001248 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001249 // here.
1250 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1251}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252
1253
1254HeapObject* HeapObject::FromAddress(Address address) {
1255 ASSERT_TAG_ALIGNED(address);
1256 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1257}
1258
1259
1260Address HeapObject::address() {
1261 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1262}
1263
1264
1265int HeapObject::Size() {
1266 return SizeFromMap(map());
1267}
1268
1269
1270void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1271 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1272 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1273}
1274
1275
1276void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1277 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1278}
1279
1280
kasper.lund7276f142008-07-30 08:49:36 +00001281bool HeapObject::IsMarked() {
1282 return map_word().IsMarked();
1283}
1284
1285
1286void HeapObject::SetMark() {
1287 ASSERT(!IsMarked());
1288 MapWord first_word = map_word();
1289 first_word.SetMark();
1290 set_map_word(first_word);
1291}
1292
1293
1294void HeapObject::ClearMark() {
1295 ASSERT(IsMarked());
1296 MapWord first_word = map_word();
1297 first_word.ClearMark();
1298 set_map_word(first_word);
1299}
1300
1301
1302bool HeapObject::IsOverflowed() {
1303 return map_word().IsOverflowed();
1304}
1305
1306
1307void HeapObject::SetOverflow() {
1308 MapWord first_word = map_word();
1309 first_word.SetOverflow();
1310 set_map_word(first_word);
1311}
1312
1313
1314void HeapObject::ClearOverflow() {
1315 ASSERT(IsOverflowed());
1316 MapWord first_word = map_word();
1317 first_word.ClearOverflow();
1318 set_map_word(first_word);
1319}
1320
1321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322double HeapNumber::value() {
1323 return READ_DOUBLE_FIELD(this, kValueOffset);
1324}
1325
1326
1327void HeapNumber::set_value(double value) {
1328 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1329}
1330
1331
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001332int HeapNumber::get_exponent() {
1333 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1334 kExponentShift) - kExponentBias;
1335}
1336
1337
1338int HeapNumber::get_sign() {
1339 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1340}
1341
1342
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001343ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001344
1345
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001346FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001347 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001348 ASSERT(array->HasValidElements());
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001349 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001350}
1351
1352
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001353void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001354 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001355 (value->map() == GetHeap()->fixed_array_map() ||
1356 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001357 ASSERT(map()->has_fast_double_elements() ==
1358 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001359 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001360 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001361 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001362}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001363
1364
1365void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1367 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368}
1369
1370
1371void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001372 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001373 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1374 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001375}
1376
1377
lrn@chromium.org303ada72010-10-27 09:33:13 +00001378MaybeObject* JSObject::ResetElements() {
1379 Object* obj;
1380 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1381 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1382 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001383 set_map(Map::cast(obj));
1384 initialize_elements();
1385 return this;
1386}
1387
1388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389ACCESSORS(Oddball, to_string, String, kToStringOffset)
1390ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1391
1392
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001393byte Oddball::kind() {
1394 return READ_BYTE_FIELD(this, kKindOffset);
1395}
1396
1397
1398void Oddball::set_kind(byte value) {
1399 WRITE_BYTE_FIELD(this, kKindOffset, value);
1400}
1401
1402
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001403Object* JSGlobalPropertyCell::value() {
1404 return READ_FIELD(this, kValueOffset);
1405}
1406
1407
1408void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1409 // The write barrier is not used for global property cells.
1410 ASSERT(!val->IsJSGlobalPropertyCell());
1411 WRITE_FIELD(this, kValueOffset, val);
1412}
1413
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001416 InstanceType type = map()->instance_type();
1417 // Check for the most common kind of JavaScript object before
1418 // falling into the generic switch. This speeds up the internal
1419 // field operations considerably on average.
1420 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1421 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001422 case JS_GLOBAL_PROXY_TYPE:
1423 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001424 case JS_GLOBAL_OBJECT_TYPE:
1425 return JSGlobalObject::kSize;
1426 case JS_BUILTINS_OBJECT_TYPE:
1427 return JSBuiltinsObject::kSize;
1428 case JS_FUNCTION_TYPE:
1429 return JSFunction::kSize;
1430 case JS_VALUE_TYPE:
1431 return JSValue::kSize;
1432 case JS_ARRAY_TYPE:
1433 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001434 case JS_WEAK_MAP_TYPE:
1435 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001436 case JS_REGEXP_TYPE:
1437 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001438 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001440 case JS_MESSAGE_OBJECT_TYPE:
1441 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442 default:
1443 UNREACHABLE();
1444 return 0;
1445 }
1446}
1447
1448
1449int JSObject::GetInternalFieldCount() {
1450 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001451 // Make sure to adjust for the number of in-object properties. These
1452 // properties do contribute to the size, but are not internal fields.
1453 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1454 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455}
1456
1457
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001458int JSObject::GetInternalFieldOffset(int index) {
1459 ASSERT(index < GetInternalFieldCount() && index >= 0);
1460 return GetHeaderSize() + (kPointerSize * index);
1461}
1462
1463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464Object* JSObject::GetInternalField(int index) {
1465 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001466 // Internal objects do follow immediately after the header, whereas in-object
1467 // properties are at the end of the object. Therefore there is no need
1468 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1470}
1471
1472
1473void JSObject::SetInternalField(int index, Object* value) {
1474 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001475 // Internal objects do follow immediately after the header, whereas in-object
1476 // properties are at the end of the object. Therefore there is no need
1477 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001478 int offset = GetHeaderSize() + (kPointerSize * index);
1479 WRITE_FIELD(this, offset, value);
1480 WRITE_BARRIER(this, offset);
1481}
1482
1483
ager@chromium.org7c537e22008-10-16 08:43:32 +00001484// Access fast-case object properties at index. The use of these routines
1485// is needed to correctly distinguish between properties stored in-object and
1486// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001487Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001488 // Adjust for the number of properties stored in the object.
1489 index -= map()->inobject_properties();
1490 if (index < 0) {
1491 int offset = map()->instance_size() + (index * kPointerSize);
1492 return READ_FIELD(this, offset);
1493 } else {
1494 ASSERT(index < properties()->length());
1495 return properties()->get(index);
1496 }
1497}
1498
1499
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001500Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001501 // Adjust for the number of properties stored in the object.
1502 index -= map()->inobject_properties();
1503 if (index < 0) {
1504 int offset = map()->instance_size() + (index * kPointerSize);
1505 WRITE_FIELD(this, offset, value);
1506 WRITE_BARRIER(this, offset);
1507 } else {
1508 ASSERT(index < properties()->length());
1509 properties()->set(index, value);
1510 }
1511 return value;
1512}
1513
1514
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001515int JSObject::GetInObjectPropertyOffset(int index) {
1516 // Adjust for the number of properties stored in the object.
1517 index -= map()->inobject_properties();
1518 ASSERT(index < 0);
1519 return map()->instance_size() + (index * kPointerSize);
1520}
1521
1522
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001523Object* JSObject::InObjectPropertyAt(int index) {
1524 // Adjust for the number of properties stored in the object.
1525 index -= map()->inobject_properties();
1526 ASSERT(index < 0);
1527 int offset = map()->instance_size() + (index * kPointerSize);
1528 return READ_FIELD(this, offset);
1529}
1530
1531
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001532Object* JSObject::InObjectPropertyAtPut(int index,
1533 Object* value,
1534 WriteBarrierMode mode) {
1535 // Adjust for the number of properties stored in the object.
1536 index -= map()->inobject_properties();
1537 ASSERT(index < 0);
1538 int offset = map()->instance_size() + (index * kPointerSize);
1539 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001540 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001541 return value;
1542}
1543
1544
1545
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001546void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001547 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001549 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550 }
1551}
1552
1553
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001554bool JSObject::HasFastProperties() {
1555 return !properties()->IsDictionary();
1556}
1557
1558
1559int JSObject::MaxFastProperties() {
1560 // Allow extra fast properties if the object has more than
1561 // kMaxFastProperties in-object properties. When this is the case,
1562 // it is very unlikely that the object is being used as a dictionary
1563 // and there is a good chance that allowing more map transitions
1564 // will be worth it.
1565 return Max(map()->inobject_properties(), kMaxFastProperties);
1566}
1567
1568
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001570 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001571 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001572 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 }
1574}
1575
1576
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001577bool Object::ToArrayIndex(uint32_t* index) {
1578 if (IsSmi()) {
1579 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580 if (value < 0) return false;
1581 *index = value;
1582 return true;
1583 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001584 if (IsHeapNumber()) {
1585 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001586 uint32_t uint_value = static_cast<uint32_t>(value);
1587 if (value == static_cast<double>(uint_value)) {
1588 *index = uint_value;
1589 return true;
1590 }
1591 }
1592 return false;
1593}
1594
1595
1596bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1597 if (!this->IsJSValue()) return false;
1598
1599 JSValue* js_value = JSValue::cast(this);
1600 if (!js_value->value()->IsString()) return false;
1601
1602 String* str = String::cast(js_value->value());
1603 if (index >= (uint32_t)str->length()) return false;
1604
1605 return true;
1606}
1607
1608
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001609FixedArrayBase* FixedArrayBase::cast(Object* object) {
1610 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1611 return reinterpret_cast<FixedArrayBase*>(object);
1612}
1613
1614
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001615Object* FixedArray::get(int index) {
1616 ASSERT(index >= 0 && index < this->length());
1617 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1618}
1619
1620
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001621void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001622 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001623 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001624 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1625 int offset = kHeaderSize + index * kPointerSize;
1626 WRITE_FIELD(this, offset, value);
1627}
1628
1629
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001630void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001631 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 ASSERT(index >= 0 && index < this->length());
1633 int offset = kHeaderSize + index * kPointerSize;
1634 WRITE_FIELD(this, offset, value);
1635 WRITE_BARRIER(this, offset);
1636}
1637
1638
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001639inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1640 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1641}
1642
1643
1644inline double FixedDoubleArray::hole_nan_as_double() {
1645 return BitCast<double, uint64_t>(kHoleNanInt64);
1646}
1647
1648
1649inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1650 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1651 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1652 return OS::nan_value();
1653}
1654
1655
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001656double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001657 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1658 map() != HEAP->fixed_array_map());
1659 ASSERT(index >= 0 && index < this->length());
1660 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1661 ASSERT(!is_the_hole_nan(result));
1662 return result;
1663}
1664
1665
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001666MaybeObject* FixedDoubleArray::get(int index) {
1667 if (is_the_hole(index)) {
1668 return GetHeap()->the_hole_value();
1669 } else {
1670 return GetHeap()->NumberFromDouble(get_scalar(index));
1671 }
1672}
1673
1674
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001675void FixedDoubleArray::set(int index, double value) {
1676 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1677 map() != HEAP->fixed_array_map());
1678 int offset = kHeaderSize + index * kDoubleSize;
1679 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1680 WRITE_DOUBLE_FIELD(this, offset, value);
1681}
1682
1683
1684void FixedDoubleArray::set_the_hole(int index) {
1685 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1686 map() != HEAP->fixed_array_map());
1687 int offset = kHeaderSize + index * kDoubleSize;
1688 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1689}
1690
1691
1692bool FixedDoubleArray::is_the_hole(int index) {
1693 int offset = kHeaderSize + index * kDoubleSize;
1694 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1695}
1696
1697
1698void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1699 int old_length = from->length();
1700 ASSERT(old_length < length());
1701 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1702 FIELD_ADDR(from, kHeaderSize),
1703 old_length * kDoubleSize);
1704 int offset = kHeaderSize + old_length * kDoubleSize;
1705 for (int current = from->length(); current < length(); ++current) {
1706 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1707 offset += kDoubleSize;
1708 }
1709}
1710
1711
1712void FixedDoubleArray::Initialize(FixedArray* from) {
1713 int old_length = from->length();
1714 ASSERT(old_length < length());
1715 for (int i = 0; i < old_length; i++) {
1716 Object* hole_or_object = from->get(i);
1717 if (hole_or_object->IsTheHole()) {
1718 set_the_hole(i);
1719 } else {
1720 set(i, hole_or_object->Number());
1721 }
1722 }
1723 int offset = kHeaderSize + old_length * kDoubleSize;
1724 for (int current = from->length(); current < length(); ++current) {
1725 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1726 offset += kDoubleSize;
1727 }
1728}
1729
1730
1731void FixedDoubleArray::Initialize(NumberDictionary* from) {
1732 int offset = kHeaderSize;
1733 for (int current = 0; current < length(); ++current) {
1734 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1735 offset += kDoubleSize;
1736 }
1737 for (int i = 0; i < from->Capacity(); i++) {
1738 Object* key = from->KeyAt(i);
1739 if (key->IsNumber()) {
1740 uint32_t entry = static_cast<uint32_t>(key->Number());
1741 set(entry, from->ValueAt(i)->Number());
1742 }
1743 }
1744}
1745
1746
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001747WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001748 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749 return UPDATE_WRITE_BARRIER;
1750}
1751
1752
1753void FixedArray::set(int index,
1754 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001755 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001756 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001757 ASSERT(index >= 0 && index < this->length());
1758 int offset = kHeaderSize + index * kPointerSize;
1759 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001760 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761}
1762
1763
1764void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001765 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001767 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1769}
1770
1771
1772void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773 ASSERT(map() != HEAP->fixed_cow_array_map());
1774 set_undefined(GetHeap(), index);
1775}
1776
1777
1778void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001779 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783}
1784
1785
ager@chromium.org236ad962008-09-25 09:45:57 +00001786void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001787 set_null(GetHeap(), index);
1788}
1789
1790
1791void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001792 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001793 ASSERT(!heap->InNewSpace(heap->null_value()));
1794 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001795}
1796
1797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001799 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001801 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1802 WRITE_FIELD(this,
1803 kHeaderSize + index * kPointerSize,
1804 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805}
1806
1807
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001808void FixedArray::set_unchecked(int index, Smi* value) {
1809 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1810 int offset = kHeaderSize + index * kPointerSize;
1811 WRITE_FIELD(this, offset, value);
1812}
1813
1814
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815void FixedArray::set_unchecked(Heap* heap,
1816 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001817 Object* value,
1818 WriteBarrierMode mode) {
1819 int offset = kHeaderSize + index * kPointerSize;
1820 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001822}
1823
1824
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001826 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001827 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1828 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001829}
1830
1831
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001832Object** FixedArray::data_start() {
1833 return HeapObject::RawField(this, kHeaderSize);
1834}
1835
1836
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001837bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001838 ASSERT(this->IsSmi() ||
1839 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001841 return this->IsSmi() || length() <= kFirstIndex;
1842}
1843
1844
1845int DescriptorArray::bit_field3_storage() {
1846 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1847 return Smi::cast(storage)->value();
1848}
1849
1850void DescriptorArray::set_bit_field3_storage(int value) {
1851 ASSERT(!IsEmpty());
1852 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001853}
1854
1855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1857 Object* tmp = array->get(first);
1858 fast_set(array, first, array->get(second));
1859 fast_set(array, second, tmp);
1860}
1861
1862
1863int DescriptorArray::Search(String* name) {
1864 SLOW_ASSERT(IsSortedNoDuplicates());
1865
1866 // Check for empty descriptor array.
1867 int nof = number_of_descriptors();
1868 if (nof == 0) return kNotFound;
1869
1870 // Fast case: do linear search for small arrays.
1871 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001872 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001873 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 }
1875
1876 // Slow case: perform binary search.
1877 return BinarySearch(name, 0, nof - 1);
1878}
1879
1880
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001881int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001882 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001883 if (number == DescriptorLookupCache::kAbsent) {
1884 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001885 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001886 }
1887 return number;
1888}
1889
1890
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891String* DescriptorArray::GetKey(int descriptor_number) {
1892 ASSERT(descriptor_number < number_of_descriptors());
1893 return String::cast(get(ToKeyIndex(descriptor_number)));
1894}
1895
1896
1897Object* DescriptorArray::GetValue(int descriptor_number) {
1898 ASSERT(descriptor_number < number_of_descriptors());
1899 return GetContentArray()->get(ToValueIndex(descriptor_number));
1900}
1901
1902
1903Smi* DescriptorArray::GetDetails(int descriptor_number) {
1904 ASSERT(descriptor_number < number_of_descriptors());
1905 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1906}
1907
1908
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001909PropertyType DescriptorArray::GetType(int descriptor_number) {
1910 ASSERT(descriptor_number < number_of_descriptors());
1911 return PropertyDetails(GetDetails(descriptor_number)).type();
1912}
1913
1914
1915int DescriptorArray::GetFieldIndex(int descriptor_number) {
1916 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1917}
1918
1919
1920JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1921 return JSFunction::cast(GetValue(descriptor_number));
1922}
1923
1924
1925Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1926 ASSERT(GetType(descriptor_number) == CALLBACKS);
1927 return GetValue(descriptor_number);
1928}
1929
1930
1931AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1932 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001933 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1934 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001935}
1936
1937
1938bool DescriptorArray::IsProperty(int descriptor_number) {
1939 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1940}
1941
1942
1943bool DescriptorArray::IsTransition(int descriptor_number) {
1944 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001945 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1946 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001947}
1948
1949
1950bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1951 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1952}
1953
1954
1955bool DescriptorArray::IsDontEnum(int descriptor_number) {
1956 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1957}
1958
1959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001960void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1961 desc->Init(GetKey(descriptor_number),
1962 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001963 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
1967void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1968 // Range check.
1969 ASSERT(descriptor_number < number_of_descriptors());
1970
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001971 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001972 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1973 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974
1975 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1976 FixedArray* content_array = GetContentArray();
1977 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1978 fast_set(content_array, ToDetailsIndex(descriptor_number),
1979 desc->GetDetails().AsSmi());
1980}
1981
1982
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001983void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1984 Descriptor desc;
1985 src->Get(src_index, &desc);
1986 Set(index, &desc);
1987}
1988
1989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001990void DescriptorArray::Swap(int first, int second) {
1991 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1992 FixedArray* content_array = GetContentArray();
1993 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1994 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1995}
1996
1997
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001998template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001999int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2000 const int kMinCapacity = 32;
2001 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2002 if (capacity < kMinCapacity) {
2003 capacity = kMinCapacity; // Guarantee min capacity.
2004 }
2005 return capacity;
2006}
2007
2008
2009template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002010int HashTable<Shape, Key>::FindEntry(Key key) {
2011 return FindEntry(GetIsolate(), key);
2012}
2013
2014
2015// Find entry for key otherwise return kNotFound.
2016template<typename Shape, typename Key>
2017int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2018 uint32_t capacity = Capacity();
2019 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2020 uint32_t count = 1;
2021 // EnsureCapacity will guarantee the hash table is never full.
2022 while (true) {
2023 Object* element = KeyAt(entry);
2024 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2025 if (element != isolate->heap()->null_value() &&
2026 Shape::IsMatch(key, element)) return entry;
2027 entry = NextProbe(entry, count++, capacity);
2028 }
2029 return kNotFound;
2030}
2031
2032
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002033bool NumberDictionary::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 false;
2036 return 0 !=
2037 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2038}
2039
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002040uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002041 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002042 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043 if (!max_index_object->IsSmi()) return 0;
2044 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2045 return value >> kRequiresSlowElementsTagSize;
2046}
2047
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002048void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002049 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002050}
2051
2052
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002053// ------------------------------------
2054// Cast operations
2055
2056
2057CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002058CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002059CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060CAST_ACCESSOR(DeoptimizationInputData)
2061CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002063CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002064CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002065CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002066CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002067CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002068CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069CAST_ACCESSOR(String)
2070CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002071CAST_ACCESSOR(SeqAsciiString)
2072CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002073CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002074CAST_ACCESSOR(ExternalString)
2075CAST_ACCESSOR(ExternalAsciiString)
2076CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002077CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002078CAST_ACCESSOR(JSObject)
2079CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002080CAST_ACCESSOR(HeapObject)
2081CAST_ACCESSOR(HeapNumber)
2082CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002083CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002084CAST_ACCESSOR(SharedFunctionInfo)
2085CAST_ACCESSOR(Map)
2086CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002087CAST_ACCESSOR(GlobalObject)
2088CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089CAST_ACCESSOR(JSGlobalObject)
2090CAST_ACCESSOR(JSBuiltinsObject)
2091CAST_ACCESSOR(Code)
2092CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002093CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002094CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002095CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002096CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002097CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002099CAST_ACCESSOR(ExternalArray)
2100CAST_ACCESSOR(ExternalByteArray)
2101CAST_ACCESSOR(ExternalUnsignedByteArray)
2102CAST_ACCESSOR(ExternalShortArray)
2103CAST_ACCESSOR(ExternalUnsignedShortArray)
2104CAST_ACCESSOR(ExternalIntArray)
2105CAST_ACCESSOR(ExternalUnsignedIntArray)
2106CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002107CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002108CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109CAST_ACCESSOR(Struct)
2110
2111
2112#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2113 STRUCT_LIST(MAKE_STRUCT_CAST)
2114#undef MAKE_STRUCT_CAST
2115
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002116
2117template <typename Shape, typename Key>
2118HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119 ASSERT(obj->IsHashTable());
2120 return reinterpret_cast<HashTable*>(obj);
2121}
2122
2123
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002124SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125
ager@chromium.orgac091b72010-05-05 07:34:42 +00002126SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002127
2128
2129uint32_t String::hash_field() {
2130 return READ_UINT32_FIELD(this, kHashFieldOffset);
2131}
2132
2133
2134void String::set_hash_field(uint32_t value) {
2135 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002136#if V8_HOST_ARCH_64_BIT
2137 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2138#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002139}
2140
2141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142bool String::Equals(String* other) {
2143 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002144 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2145 return false;
2146 }
2147 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002148}
2149
2150
lrn@chromium.org303ada72010-10-27 09:33:13 +00002151MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002152 if (!StringShape(this).IsCons()) return this;
2153 ConsString* cons = ConsString::cast(this);
2154 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002155 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156}
2157
2158
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002159String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002160 MaybeObject* flat = TryFlatten(pretenure);
2161 Object* successfully_flattened;
2162 if (flat->ToObject(&successfully_flattened)) {
2163 return String::cast(successfully_flattened);
2164 }
2165 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002166}
2167
2168
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002169uint16_t String::Get(int index) {
2170 ASSERT(index >= 0 && index < length());
2171 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002172 case kSeqStringTag | kAsciiStringTag:
2173 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2174 case kSeqStringTag | kTwoByteStringTag:
2175 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2176 case kConsStringTag | kAsciiStringTag:
2177 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002178 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002179 case kExternalStringTag | kAsciiStringTag:
2180 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2181 case kExternalStringTag | kTwoByteStringTag:
2182 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183 default:
2184 break;
2185 }
2186
2187 UNREACHABLE();
2188 return 0;
2189}
2190
2191
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002192void String::Set(int index, uint16_t value) {
2193 ASSERT(index >= 0 && index < length());
2194 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195
ager@chromium.org5ec48922009-05-05 07:25:34 +00002196 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002197 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2198 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199}
2200
2201
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002202bool String::IsFlat() {
2203 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002204 case kConsStringTag: {
2205 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002206 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002207 return second->length() == 0;
2208 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002209 default:
2210 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211 }
2212}
2213
2214
ager@chromium.org7c537e22008-10-16 08:43:32 +00002215uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 ASSERT(index >= 0 && index < length());
2217 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2218}
2219
2220
ager@chromium.org7c537e22008-10-16 08:43:32 +00002221void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2223 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2224 static_cast<byte>(value));
2225}
2226
2227
ager@chromium.org7c537e22008-10-16 08:43:32 +00002228Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229 return FIELD_ADDR(this, kHeaderSize);
2230}
2231
2232
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002233char* SeqAsciiString::GetChars() {
2234 return reinterpret_cast<char*>(GetCharsAddress());
2235}
2236
2237
ager@chromium.org7c537e22008-10-16 08:43:32 +00002238Address SeqTwoByteString::GetCharsAddress() {
2239 return FIELD_ADDR(this, kHeaderSize);
2240}
2241
2242
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002243uc16* SeqTwoByteString::GetChars() {
2244 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2245}
2246
2247
ager@chromium.org7c537e22008-10-16 08:43:32 +00002248uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002249 ASSERT(index >= 0 && index < length());
2250 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2251}
2252
2253
ager@chromium.org7c537e22008-10-16 08:43:32 +00002254void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002255 ASSERT(index >= 0 && index < length());
2256 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2257}
2258
2259
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002260int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002261 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002262}
2263
2264
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002265int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002266 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267}
2268
2269
ager@chromium.org870a0b62008-11-04 11:43:05 +00002270String* ConsString::first() {
2271 return String::cast(READ_FIELD(this, kFirstOffset));
2272}
2273
2274
2275Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276 return READ_FIELD(this, kFirstOffset);
2277}
2278
2279
ager@chromium.org870a0b62008-11-04 11:43:05 +00002280void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002282 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002283}
2284
2285
ager@chromium.org870a0b62008-11-04 11:43:05 +00002286String* ConsString::second() {
2287 return String::cast(READ_FIELD(this, kSecondOffset));
2288}
2289
2290
2291Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 return READ_FIELD(this, kSecondOffset);
2293}
2294
2295
ager@chromium.org870a0b62008-11-04 11:43:05 +00002296void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002298 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299}
2300
2301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2303 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2304}
2305
2306
2307void ExternalAsciiString::set_resource(
2308 ExternalAsciiString::Resource* resource) {
2309 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2310}
2311
2312
2313ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2314 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2315}
2316
2317
2318void ExternalTwoByteString::set_resource(
2319 ExternalTwoByteString::Resource* resource) {
2320 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2321}
2322
2323
ager@chromium.orgac091b72010-05-05 07:34:42 +00002324void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002325 set_finger_index(kEntriesIndex);
2326 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002327}
2328
2329
2330void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002331 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002332 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002333 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002334 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002335 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002336 MakeZeroSize();
2337}
2338
2339
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002340int JSFunctionResultCache::size() {
2341 return Smi::cast(get(kCacheSizeIndex))->value();
2342}
2343
2344
2345void JSFunctionResultCache::set_size(int size) {
2346 set(kCacheSizeIndex, Smi::FromInt(size));
2347}
2348
2349
2350int JSFunctionResultCache::finger_index() {
2351 return Smi::cast(get(kFingerIndex))->value();
2352}
2353
2354
2355void JSFunctionResultCache::set_finger_index(int finger_index) {
2356 set(kFingerIndex, Smi::FromInt(finger_index));
2357}
2358
2359
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360byte ByteArray::get(int index) {
2361 ASSERT(index >= 0 && index < this->length());
2362 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2363}
2364
2365
2366void ByteArray::set(int index, byte value) {
2367 ASSERT(index >= 0 && index < this->length());
2368 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2369}
2370
2371
2372int ByteArray::get_int(int index) {
2373 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2374 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2375}
2376
2377
2378ByteArray* ByteArray::FromDataStartAddress(Address address) {
2379 ASSERT_TAG_ALIGNED(address);
2380 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2381}
2382
2383
2384Address ByteArray::GetDataStartAddress() {
2385 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2386}
2387
2388
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002389uint8_t* ExternalPixelArray::external_pixel_pointer() {
2390 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002391}
2392
2393
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002394uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002395 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002396 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002397 return ptr[index];
2398}
2399
2400
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002401MaybeObject* ExternalPixelArray::get(int index) {
2402 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2403}
2404
2405
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002406void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002407 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002408 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002409 ptr[index] = value;
2410}
2411
2412
ager@chromium.org3811b432009-10-28 14:53:37 +00002413void* ExternalArray::external_pointer() {
2414 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2415 return reinterpret_cast<void*>(ptr);
2416}
2417
2418
2419void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2420 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2421 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2422}
2423
2424
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002425int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002426 ASSERT((index >= 0) && (index < this->length()));
2427 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2428 return ptr[index];
2429}
2430
2431
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002432MaybeObject* ExternalByteArray::get(int index) {
2433 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2434}
2435
2436
ager@chromium.org3811b432009-10-28 14:53:37 +00002437void ExternalByteArray::set(int index, int8_t value) {
2438 ASSERT((index >= 0) && (index < this->length()));
2439 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2440 ptr[index] = value;
2441}
2442
2443
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002444uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002445 ASSERT((index >= 0) && (index < this->length()));
2446 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2447 return ptr[index];
2448}
2449
2450
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002451MaybeObject* ExternalUnsignedByteArray::get(int index) {
2452 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2453}
2454
2455
ager@chromium.org3811b432009-10-28 14:53:37 +00002456void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2457 ASSERT((index >= 0) && (index < this->length()));
2458 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2459 ptr[index] = value;
2460}
2461
2462
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002463int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002464 ASSERT((index >= 0) && (index < this->length()));
2465 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2466 return ptr[index];
2467}
2468
2469
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002470MaybeObject* ExternalShortArray::get(int index) {
2471 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2472}
2473
2474
ager@chromium.org3811b432009-10-28 14:53:37 +00002475void ExternalShortArray::set(int index, int16_t value) {
2476 ASSERT((index >= 0) && (index < this->length()));
2477 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2478 ptr[index] = value;
2479}
2480
2481
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002482uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002483 ASSERT((index >= 0) && (index < this->length()));
2484 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2485 return ptr[index];
2486}
2487
2488
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002489MaybeObject* ExternalUnsignedShortArray::get(int index) {
2490 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2491}
2492
2493
ager@chromium.org3811b432009-10-28 14:53:37 +00002494void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2495 ASSERT((index >= 0) && (index < this->length()));
2496 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2497 ptr[index] = value;
2498}
2499
2500
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002501int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002502 ASSERT((index >= 0) && (index < this->length()));
2503 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2504 return ptr[index];
2505}
2506
2507
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002508MaybeObject* ExternalIntArray::get(int index) {
2509 return GetHeap()->NumberFromInt32(get_scalar(index));
2510}
2511
2512
ager@chromium.org3811b432009-10-28 14:53:37 +00002513void ExternalIntArray::set(int index, int32_t value) {
2514 ASSERT((index >= 0) && (index < this->length()));
2515 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2516 ptr[index] = value;
2517}
2518
2519
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002520uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002521 ASSERT((index >= 0) && (index < this->length()));
2522 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2523 return ptr[index];
2524}
2525
2526
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002527MaybeObject* ExternalUnsignedIntArray::get(int index) {
2528 return GetHeap()->NumberFromUint32(get_scalar(index));
2529}
2530
2531
ager@chromium.org3811b432009-10-28 14:53:37 +00002532void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2533 ASSERT((index >= 0) && (index < this->length()));
2534 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2535 ptr[index] = value;
2536}
2537
2538
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002539float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002540 ASSERT((index >= 0) && (index < this->length()));
2541 float* ptr = static_cast<float*>(external_pointer());
2542 return ptr[index];
2543}
2544
2545
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002546MaybeObject* ExternalFloatArray::get(int index) {
2547 return GetHeap()->NumberFromDouble(get_scalar(index));
2548}
2549
2550
ager@chromium.org3811b432009-10-28 14:53:37 +00002551void ExternalFloatArray::set(int index, float value) {
2552 ASSERT((index >= 0) && (index < this->length()));
2553 float* ptr = static_cast<float*>(external_pointer());
2554 ptr[index] = value;
2555}
2556
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002557
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002558double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002559 ASSERT((index >= 0) && (index < this->length()));
2560 double* ptr = static_cast<double*>(external_pointer());
2561 return ptr[index];
2562}
2563
2564
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002565MaybeObject* ExternalDoubleArray::get(int index) {
2566 return GetHeap()->NumberFromDouble(get_scalar(index));
2567}
2568
2569
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002570void ExternalDoubleArray::set(int index, double value) {
2571 ASSERT((index >= 0) && (index < this->length()));
2572 double* ptr = static_cast<double*>(external_pointer());
2573 ptr[index] = value;
2574}
2575
2576
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002577int Map::visitor_id() {
2578 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2579}
2580
2581
2582void Map::set_visitor_id(int id) {
2583 ASSERT(0 <= id && id < 256);
2584 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2585}
2586
ager@chromium.org3811b432009-10-28 14:53:37 +00002587
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002588int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002589 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2590}
2591
2592
2593int Map::inobject_properties() {
2594 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002595}
2596
2597
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002598int Map::pre_allocated_property_fields() {
2599 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2600}
2601
2602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002604 int instance_size = map->instance_size();
2605 if (instance_size != kVariableSizeSentinel) return instance_size;
2606 // We can ignore the "symbol" bit becase it is only set for symbols
2607 // and implies a string type.
2608 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002609 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002611 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002613 if (instance_type == ASCII_STRING_TYPE) {
2614 return SeqAsciiString::SizeFor(
2615 reinterpret_cast<SeqAsciiString*>(this)->length());
2616 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002617 if (instance_type == BYTE_ARRAY_TYPE) {
2618 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2619 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002620 if (instance_type == STRING_TYPE) {
2621 return SeqTwoByteString::SizeFor(
2622 reinterpret_cast<SeqTwoByteString*>(this)->length());
2623 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002624 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2625 return FixedDoubleArray::SizeFor(
2626 reinterpret_cast<FixedDoubleArray*>(this)->length());
2627 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002628 ASSERT(instance_type == CODE_TYPE);
2629 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630}
2631
2632
2633void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002634 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002635 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636 ASSERT(0 <= value && value < 256);
2637 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2638}
2639
2640
ager@chromium.org7c537e22008-10-16 08:43:32 +00002641void Map::set_inobject_properties(int value) {
2642 ASSERT(0 <= value && value < 256);
2643 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2644}
2645
2646
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002647void Map::set_pre_allocated_property_fields(int value) {
2648 ASSERT(0 <= value && value < 256);
2649 WRITE_BYTE_FIELD(this,
2650 kPreAllocatedPropertyFieldsOffset,
2651 static_cast<byte>(value));
2652}
2653
2654
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002655InstanceType Map::instance_type() {
2656 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2657}
2658
2659
2660void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002661 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2662}
2663
2664
2665int Map::unused_property_fields() {
2666 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2667}
2668
2669
2670void Map::set_unused_property_fields(int value) {
2671 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2672}
2673
2674
2675byte Map::bit_field() {
2676 return READ_BYTE_FIELD(this, kBitFieldOffset);
2677}
2678
2679
2680void Map::set_bit_field(byte value) {
2681 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2682}
2683
2684
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002685byte Map::bit_field2() {
2686 return READ_BYTE_FIELD(this, kBitField2Offset);
2687}
2688
2689
2690void Map::set_bit_field2(byte value) {
2691 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2692}
2693
2694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002695void Map::set_non_instance_prototype(bool value) {
2696 if (value) {
2697 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2698 } else {
2699 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2700 }
2701}
2702
2703
2704bool Map::has_non_instance_prototype() {
2705 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2706}
2707
2708
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002709void Map::set_function_with_prototype(bool value) {
2710 if (value) {
2711 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2712 } else {
2713 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2714 }
2715}
2716
2717
2718bool Map::function_with_prototype() {
2719 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2720}
2721
2722
ager@chromium.org870a0b62008-11-04 11:43:05 +00002723void Map::set_is_access_check_needed(bool access_check_needed) {
2724 if (access_check_needed) {
2725 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2726 } else {
2727 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2728 }
2729}
2730
2731
2732bool Map::is_access_check_needed() {
2733 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2734}
2735
2736
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002737void Map::set_is_extensible(bool value) {
2738 if (value) {
2739 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2740 } else {
2741 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2742 }
2743}
2744
2745bool Map::is_extensible() {
2746 return ((1 << kIsExtensible) & bit_field2()) != 0;
2747}
2748
2749
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002750void Map::set_attached_to_shared_function_info(bool value) {
2751 if (value) {
2752 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2753 } else {
2754 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2755 }
2756}
2757
2758bool Map::attached_to_shared_function_info() {
2759 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2760}
2761
2762
2763void Map::set_is_shared(bool value) {
2764 if (value) {
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 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002767 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002768 }
2769}
2770
2771bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002772 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002773}
2774
2775
2776JSFunction* Map::unchecked_constructor() {
2777 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2778}
2779
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002780
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002781FixedArray* Map::unchecked_prototype_transitions() {
2782 return reinterpret_cast<FixedArray*>(
2783 READ_FIELD(this, kPrototypeTransitionsOffset));
2784}
2785
2786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787Code::Flags Code::flags() {
2788 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2789}
2790
2791
2792void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002793 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002794 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002795 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2796 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002797 ExtractArgumentsCountFromFlags(flags) >= 0);
2798 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2799}
2800
2801
2802Code::Kind Code::kind() {
2803 return ExtractKindFromFlags(flags());
2804}
2805
2806
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002807InLoopFlag Code::ic_in_loop() {
2808 return ExtractICInLoopFromFlags(flags());
2809}
2810
2811
kasper.lund7276f142008-07-30 08:49:36 +00002812InlineCacheState Code::ic_state() {
2813 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814 // Only allow uninitialized or debugger states for non-IC code
2815 // objects. This is used in the debugger to determine whether or not
2816 // a call to code object has been replaced with a debug break call.
2817 ASSERT(is_inline_cache_stub() ||
2818 result == UNINITIALIZED ||
2819 result == DEBUG_BREAK ||
2820 result == DEBUG_PREPARE_STEP_IN);
2821 return result;
2822}
2823
2824
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002825Code::ExtraICState Code::extra_ic_state() {
2826 ASSERT(is_inline_cache_stub());
2827 return ExtractExtraICStateFromFlags(flags());
2828}
2829
2830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832 return ExtractTypeFromFlags(flags());
2833}
2834
2835
2836int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002837 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002838 return ExtractArgumentsCountFromFlags(flags());
2839}
2840
2841
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002842int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002843 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002844 kind() == UNARY_OP_IC ||
2845 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002846 kind() == COMPARE_IC ||
2847 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002848 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002849}
2850
2851
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002852void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002853 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002854 kind() == UNARY_OP_IC ||
2855 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002856 kind() == COMPARE_IC ||
2857 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002858 ASSERT(0 <= major && major < 256);
2859 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002860}
2861
2862
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863bool Code::optimizable() {
2864 ASSERT(kind() == FUNCTION);
2865 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2866}
2867
2868
2869void Code::set_optimizable(bool value) {
2870 ASSERT(kind() == FUNCTION);
2871 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2872}
2873
2874
2875bool Code::has_deoptimization_support() {
2876 ASSERT(kind() == FUNCTION);
2877 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2878}
2879
2880
2881void Code::set_has_deoptimization_support(bool value) {
2882 ASSERT(kind() == FUNCTION);
2883 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2884}
2885
2886
2887int Code::allow_osr_at_loop_nesting_level() {
2888 ASSERT(kind() == FUNCTION);
2889 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2890}
2891
2892
2893void Code::set_allow_osr_at_loop_nesting_level(int level) {
2894 ASSERT(kind() == FUNCTION);
2895 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2896 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2897}
2898
2899
2900unsigned Code::stack_slots() {
2901 ASSERT(kind() == OPTIMIZED_FUNCTION);
2902 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2903}
2904
2905
2906void Code::set_stack_slots(unsigned slots) {
2907 ASSERT(kind() == OPTIMIZED_FUNCTION);
2908 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2909}
2910
2911
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002912unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002914 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002915}
2916
2917
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002918void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002919 ASSERT(kind() == OPTIMIZED_FUNCTION);
2920 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002921 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002922}
2923
2924
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002925unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002926 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002927 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928}
2929
2930
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002931void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 ASSERT(kind() == FUNCTION);
2933 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002934 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935}
2936
2937
2938CheckType Code::check_type() {
2939 ASSERT(is_call_stub() || is_keyed_call_stub());
2940 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2941 return static_cast<CheckType>(type);
2942}
2943
2944
2945void Code::set_check_type(CheckType value) {
2946 ASSERT(is_call_stub() || is_keyed_call_stub());
2947 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2948}
2949
2950
danno@chromium.org40cb8782011-05-25 07:58:50 +00002951byte Code::unary_op_type() {
2952 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002953 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2954}
2955
2956
danno@chromium.org40cb8782011-05-25 07:58:50 +00002957void Code::set_unary_op_type(byte value) {
2958 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002959 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2960}
2961
2962
danno@chromium.org40cb8782011-05-25 07:58:50 +00002963byte Code::binary_op_type() {
2964 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002965 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2966}
2967
2968
danno@chromium.org40cb8782011-05-25 07:58:50 +00002969void Code::set_binary_op_type(byte value) {
2970 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002971 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2972}
2973
2974
danno@chromium.org40cb8782011-05-25 07:58:50 +00002975byte Code::binary_op_result_type() {
2976 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2978}
2979
2980
danno@chromium.org40cb8782011-05-25 07:58:50 +00002981void Code::set_binary_op_result_type(byte value) {
2982 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2984}
2985
2986
2987byte Code::compare_state() {
2988 ASSERT(is_compare_ic_stub());
2989 return READ_BYTE_FIELD(this, kCompareStateOffset);
2990}
2991
2992
2993void Code::set_compare_state(byte value) {
2994 ASSERT(is_compare_ic_stub());
2995 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2996}
2997
2998
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002999byte Code::to_boolean_state() {
3000 ASSERT(is_to_boolean_ic_stub());
3001 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3002}
3003
3004
3005void Code::set_to_boolean_state(byte value) {
3006 ASSERT(is_to_boolean_ic_stub());
3007 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3008}
3009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003010bool Code::is_inline_cache_stub() {
3011 Kind kind = this->kind();
3012 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3013}
3014
3015
3016Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003017 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00003018 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003019 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003021 int argc,
3022 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003023 // Extra IC state is only allowed for call IC stubs or for store IC
3024 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003025 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003026 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003027 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003028 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003029 // Compute the bit mask.
3030 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003031 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00003032 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003033 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003034 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003036 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003037 // Cast to flags and validate result before returning it.
3038 Flags result = static_cast<Flags>(bits);
3039 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00003040 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003041 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003042 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003043 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003044 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
3045 return result;
3046}
3047
3048
3049Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3050 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003051 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003052 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003053 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003054 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003055 return ComputeFlags(
3056 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057}
3058
3059
3060Code::Kind Code::ExtractKindFromFlags(Flags flags) {
3061 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
3062 return static_cast<Kind>(bits);
3063}
3064
3065
kasper.lund7276f142008-07-30 08:49:36 +00003066InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
3067 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003068 return static_cast<InlineCacheState>(bits);
3069}
3070
3071
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003072Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3073 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
3074 return static_cast<ExtraICState>(bits);
3075}
3076
3077
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003078InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
3079 int bits = (flags & kFlagsICInLoopMask);
3080 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3081}
3082
3083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003084PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3085 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3086 return static_cast<PropertyType>(bits);
3087}
3088
3089
3090int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3091 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3092}
3093
3094
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003095InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3096 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3097 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3098}
3099
3100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003101Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3102 int bits = flags & ~kFlagsTypeMask;
3103 return static_cast<Flags>(bits);
3104}
3105
3106
ager@chromium.org8bb60582008-12-11 12:02:20 +00003107Code* Code::GetCodeFromTargetAddress(Address address) {
3108 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3109 // GetCodeFromTargetAddress might be called when marking objects during mark
3110 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3111 // Code::cast. Code::cast does not work when the object's map is
3112 // marked.
3113 Code* result = reinterpret_cast<Code*>(code);
3114 return result;
3115}
3116
3117
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003118Isolate* Map::isolate() {
3119 return heap()->isolate();
3120}
3121
3122
3123Heap* Map::heap() {
3124 // NOTE: address() helper is not used to save one instruction.
3125 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3126 ASSERT(heap != NULL);
3127 ASSERT(heap->isolate() == Isolate::Current());
3128 return heap;
3129}
3130
3131
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003132Heap* Code::heap() {
3133 // NOTE: address() helper is not used to save one instruction.
3134 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3135 ASSERT(heap != NULL);
3136 ASSERT(heap->isolate() == Isolate::Current());
3137 return heap;
3138}
3139
3140
3141Isolate* Code::isolate() {
3142 return heap()->isolate();
3143}
3144
3145
3146Heap* JSGlobalPropertyCell::heap() {
3147 // NOTE: address() helper is not used to save one instruction.
3148 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3149 ASSERT(heap != NULL);
3150 ASSERT(heap->isolate() == Isolate::Current());
3151 return heap;
3152}
3153
3154
3155Isolate* JSGlobalPropertyCell::isolate() {
3156 return heap()->isolate();
3157}
3158
3159
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003160Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3161 return HeapObject::
3162 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3163}
3164
3165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003166Object* Map::prototype() {
3167 return READ_FIELD(this, kPrototypeOffset);
3168}
3169
3170
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003171void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003172 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003173 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003174 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003175}
3176
3177
lrn@chromium.org303ada72010-10-27 09:33:13 +00003178MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003179 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003180 Object* obj;
3181 { MaybeObject* maybe_obj = CopyDropTransitions();
3182 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3183 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003184 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003185 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003186 isolate()->counters()->map_to_fast_elements()->Increment();
3187 return new_map;
3188}
3189
3190
3191MaybeObject* Map::GetFastDoubleElementsMap() {
3192 if (has_fast_double_elements()) return this;
3193 Object* obj;
3194 { MaybeObject* maybe_obj = CopyDropTransitions();
3195 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3196 }
3197 Map* new_map = Map::cast(obj);
3198 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3199 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003200 return new_map;
3201}
3202
3203
lrn@chromium.org303ada72010-10-27 09:33:13 +00003204MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003205 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003206 Object* obj;
3207 { MaybeObject* maybe_obj = CopyDropTransitions();
3208 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3209 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003210 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003211 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003212 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003213 return new_map;
3214}
3215
3216
danno@chromium.org40cb8782011-05-25 07:58:50 +00003217DescriptorArray* Map::instance_descriptors() {
3218 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3219 if (object->IsSmi()) {
3220 return HEAP->empty_descriptor_array();
3221 } else {
3222 return DescriptorArray::cast(object);
3223 }
3224}
3225
3226
3227void Map::init_instance_descriptors() {
3228 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3229}
3230
3231
3232void Map::clear_instance_descriptors() {
3233 Object* object = READ_FIELD(this,
3234 kInstanceDescriptorsOrBitField3Offset);
3235 if (!object->IsSmi()) {
3236 WRITE_FIELD(
3237 this,
3238 kInstanceDescriptorsOrBitField3Offset,
3239 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3240 }
3241}
3242
3243
3244void Map::set_instance_descriptors(DescriptorArray* value,
3245 WriteBarrierMode mode) {
3246 Object* object = READ_FIELD(this,
3247 kInstanceDescriptorsOrBitField3Offset);
3248 if (value == isolate()->heap()->empty_descriptor_array()) {
3249 clear_instance_descriptors();
3250 return;
3251 } else {
3252 if (object->IsSmi()) {
3253 value->set_bit_field3_storage(Smi::cast(object)->value());
3254 } else {
3255 value->set_bit_field3_storage(
3256 DescriptorArray::cast(object)->bit_field3_storage());
3257 }
3258 }
3259 ASSERT(!is_shared());
3260 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3261 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3262 this,
3263 kInstanceDescriptorsOrBitField3Offset,
3264 mode);
3265}
3266
3267
3268int Map::bit_field3() {
3269 Object* object = READ_FIELD(this,
3270 kInstanceDescriptorsOrBitField3Offset);
3271 if (object->IsSmi()) {
3272 return Smi::cast(object)->value();
3273 } else {
3274 return DescriptorArray::cast(object)->bit_field3_storage();
3275 }
3276}
3277
3278
3279void Map::set_bit_field3(int value) {
3280 ASSERT(Smi::IsValid(value));
3281 Object* object = READ_FIELD(this,
3282 kInstanceDescriptorsOrBitField3Offset);
3283 if (object->IsSmi()) {
3284 WRITE_FIELD(this,
3285 kInstanceDescriptorsOrBitField3Offset,
3286 Smi::FromInt(value));
3287 } else {
3288 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3289 }
3290}
3291
3292
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003293ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003294ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003295ACCESSORS(Map, constructor, Object, kConstructorOffset)
3296
3297ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3298ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003299ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3300 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003301
3302ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3303ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003304ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003306ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307
3308ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3309ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3310ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3311ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3312ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3313
3314ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3315ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3316ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3317
3318ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3319ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3320ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3321ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3322ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3323ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3324
3325ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3326ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3327
3328ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3329ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3330
3331ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3332ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003333ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3334 kPropertyAccessorsOffset)
3335ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3336 kPrototypeTemplateOffset)
3337ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3338ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3339 kNamedPropertyHandlerOffset)
3340ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3341 kIndexedPropertyHandlerOffset)
3342ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3343 kInstanceTemplateOffset)
3344ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3345ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003346ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3347 kInstanceCallHandlerOffset)
3348ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3349 kAccessCheckInfoOffset)
3350ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3351
3352ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003353ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3354 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003355
3356ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3357ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3358
3359ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3360
3361ACCESSORS(Script, source, Object, kSourceOffset)
3362ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003363ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3365ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003366ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003367ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003368ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003370ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003371ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003372ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003373ACCESSORS(Script, eval_from_instructions_offset, Smi,
3374 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003376#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003377ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3378ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3379ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3380ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3381
3382ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3383ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3384ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3385ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003386#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003387
3388ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003389ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3390ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3392 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003393ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003394ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3395ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003396ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003397ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3398 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003399
3400BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3401 kHiddenPrototypeBit)
3402BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3403BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3404 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003405BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3406 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003407BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3408 kIsExpressionBit)
3409BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3410 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003411BOOL_GETTER(SharedFunctionInfo,
3412 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003413 has_only_simple_this_property_assignments,
3414 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003415BOOL_ACCESSORS(SharedFunctionInfo,
3416 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003417 allows_lazy_compilation,
3418 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003419BOOL_ACCESSORS(SharedFunctionInfo,
3420 compiler_hints,
3421 uses_arguments,
3422 kUsesArguments)
3423BOOL_ACCESSORS(SharedFunctionInfo,
3424 compiler_hints,
3425 has_duplicate_parameters,
3426 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003428
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003429#if V8_HOST_ARCH_32_BIT
3430SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3431SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003432 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003433SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003434 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003435SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3436SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003437 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003438SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3439SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003440 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003441SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003442 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003443SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003444 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003446#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003447
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003448#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003449 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003450 int holder::name() { \
3451 int value = READ_INT_FIELD(this, offset); \
3452 ASSERT(kHeapObjectTag == 1); \
3453 ASSERT((value & kHeapObjectTag) == 0); \
3454 return value >> 1; \
3455 } \
3456 void holder::set_##name(int value) { \
3457 ASSERT(kHeapObjectTag == 1); \
3458 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3459 (value & 0xC0000000) == 0x000000000); \
3460 WRITE_INT_FIELD(this, \
3461 offset, \
3462 (value << 1) & ~kHeapObjectTag); \
3463 }
3464
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003465#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3466 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003467 INT_ACCESSORS(holder, name, offset)
3468
3469
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003470PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003471PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3472 formal_parameter_count,
3473 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003474
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003475PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3476 expected_nof_properties,
3477 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003478PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3479
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003480PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3481PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3482 start_position_and_type,
3483 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003484
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003485PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3486 function_token_position,
3487 kFunctionTokenPositionOffset)
3488PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3489 compiler_hints,
3490 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003491
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003492PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3493 this_property_assignments_count,
3494 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003496#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003497
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003498
3499int SharedFunctionInfo::construction_count() {
3500 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3501}
3502
3503
3504void SharedFunctionInfo::set_construction_count(int value) {
3505 ASSERT(0 <= value && value < 256);
3506 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3507}
3508
3509
whesse@chromium.org7b260152011-06-20 15:33:18 +00003510BOOL_ACCESSORS(SharedFunctionInfo,
3511 compiler_hints,
3512 live_objects_may_exist,
3513 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003514
3515
3516bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003517 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003518}
3519
3520
whesse@chromium.org7b260152011-06-20 15:33:18 +00003521BOOL_GETTER(SharedFunctionInfo,
3522 compiler_hints,
3523 optimization_disabled,
3524 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003525
3526
3527void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3528 set_compiler_hints(BooleanBit::set(compiler_hints(),
3529 kOptimizationDisabled,
3530 disable));
3531 // If disabling optimizations we reflect that in the code object so
3532 // it will not be counted as optimizable code.
3533 if ((code()->kind() == Code::FUNCTION) && disable) {
3534 code()->set_optimizable(false);
3535 }
3536}
3537
3538
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003539BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003540 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003541BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3542BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3543 name_should_print_as_anonymous,
3544 kNameShouldPrintAsAnonymous)
3545BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3546BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003547
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003548ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3549ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3550
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003551ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3552
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003553bool Script::HasValidSource() {
3554 Object* src = this->source();
3555 if (!src->IsString()) return true;
3556 String* src_str = String::cast(src);
3557 if (!StringShape(src_str).IsExternal()) return true;
3558 if (src_str->IsAsciiRepresentation()) {
3559 return ExternalAsciiString::cast(src)->resource() != NULL;
3560 } else if (src_str->IsTwoByteRepresentation()) {
3561 return ExternalTwoByteString::cast(src)->resource() != NULL;
3562 }
3563 return true;
3564}
3565
3566
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003567void SharedFunctionInfo::DontAdaptArguments() {
3568 ASSERT(code()->kind() == Code::BUILTIN);
3569 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3570}
3571
3572
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003573int SharedFunctionInfo::start_position() {
3574 return start_position_and_type() >> kStartPositionShift;
3575}
3576
3577
3578void SharedFunctionInfo::set_start_position(int start_position) {
3579 set_start_position_and_type((start_position << kStartPositionShift)
3580 | (start_position_and_type() & ~kStartPositionMask));
3581}
3582
3583
3584Code* SharedFunctionInfo::code() {
3585 return Code::cast(READ_FIELD(this, kCodeOffset));
3586}
3587
3588
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003589Code* SharedFunctionInfo::unchecked_code() {
3590 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3591}
3592
3593
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003594void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003595 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003596 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003597}
3598
3599
ager@chromium.orgb5737492010-07-15 09:29:43 +00003600SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3601 return reinterpret_cast<SerializedScopeInfo*>(
3602 READ_FIELD(this, kScopeInfoOffset));
3603}
3604
3605
3606void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3607 WriteBarrierMode mode) {
3608 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003609 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003610}
3611
3612
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613Smi* SharedFunctionInfo::deopt_counter() {
3614 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3615}
3616
3617
3618void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3619 WRITE_FIELD(this, kDeoptCounterOffset, value);
3620}
3621
3622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003623bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003624 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003625 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003626}
3627
3628
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003629bool SharedFunctionInfo::IsApiFunction() {
3630 return function_data()->IsFunctionTemplateInfo();
3631}
3632
3633
3634FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3635 ASSERT(IsApiFunction());
3636 return FunctionTemplateInfo::cast(function_data());
3637}
3638
3639
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003640bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003641 return function_data()->IsSmi();
3642}
3643
3644
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003645BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3646 ASSERT(HasBuiltinFunctionId());
3647 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003648}
3649
3650
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003651int SharedFunctionInfo::code_age() {
3652 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3653}
3654
3655
3656void SharedFunctionInfo::set_code_age(int code_age) {
3657 set_compiler_hints(compiler_hints() |
3658 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3659}
3660
3661
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662bool SharedFunctionInfo::has_deoptimization_support() {
3663 Code* code = this->code();
3664 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3665}
3666
3667
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003668bool JSFunction::IsBuiltin() {
3669 return context()->global()->IsJSBuiltinsObject();
3670}
3671
3672
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003673bool JSFunction::NeedsArgumentsAdaption() {
3674 return shared()->formal_parameter_count() !=
3675 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3676}
3677
3678
3679bool JSFunction::IsOptimized() {
3680 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3681}
3682
3683
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003684bool JSFunction::IsOptimizable() {
3685 return code()->kind() == Code::FUNCTION && code()->optimizable();
3686}
3687
3688
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003689bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003690 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691}
3692
3693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003695 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003696}
3697
3698
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003699Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003700 return reinterpret_cast<Code*>(
3701 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003702}
3703
3704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003706 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003707 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003708 Address entry = value->entry();
3709 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003710}
3711
3712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713void JSFunction::ReplaceCode(Code* code) {
3714 bool was_optimized = IsOptimized();
3715 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3716
3717 set_code(code);
3718
3719 // Add/remove the function from the list of optimized functions for this
3720 // context based on the state change.
3721 if (!was_optimized && is_optimized) {
3722 context()->global_context()->AddOptimizedFunction(this);
3723 }
3724 if (was_optimized && !is_optimized) {
3725 context()->global_context()->RemoveOptimizedFunction(this);
3726 }
3727}
3728
3729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003730Context* JSFunction::context() {
3731 return Context::cast(READ_FIELD(this, kContextOffset));
3732}
3733
3734
3735Object* JSFunction::unchecked_context() {
3736 return READ_FIELD(this, kContextOffset);
3737}
3738
3739
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003740SharedFunctionInfo* JSFunction::unchecked_shared() {
3741 return reinterpret_cast<SharedFunctionInfo*>(
3742 READ_FIELD(this, kSharedFunctionInfoOffset));
3743}
3744
3745
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003747 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003748 WRITE_FIELD(this, kContextOffset, value);
3749 WRITE_BARRIER(this, kContextOffset);
3750}
3751
3752ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3753 kPrototypeOrInitialMapOffset)
3754
3755
3756Map* JSFunction::initial_map() {
3757 return Map::cast(prototype_or_initial_map());
3758}
3759
3760
3761void JSFunction::set_initial_map(Map* value) {
3762 set_prototype_or_initial_map(value);
3763}
3764
3765
3766bool JSFunction::has_initial_map() {
3767 return prototype_or_initial_map()->IsMap();
3768}
3769
3770
3771bool JSFunction::has_instance_prototype() {
3772 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3773}
3774
3775
3776bool JSFunction::has_prototype() {
3777 return map()->has_non_instance_prototype() || has_instance_prototype();
3778}
3779
3780
3781Object* JSFunction::instance_prototype() {
3782 ASSERT(has_instance_prototype());
3783 if (has_initial_map()) return initial_map()->prototype();
3784 // When there is no initial map and the prototype is a JSObject, the
3785 // initial map field is used for the prototype field.
3786 return prototype_or_initial_map();
3787}
3788
3789
3790Object* JSFunction::prototype() {
3791 ASSERT(has_prototype());
3792 // If the function's prototype property has been set to a non-JSObject
3793 // value, that value is stored in the constructor field of the map.
3794 if (map()->has_non_instance_prototype()) return map()->constructor();
3795 return instance_prototype();
3796}
3797
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003798bool JSFunction::should_have_prototype() {
3799 return map()->function_with_prototype();
3800}
3801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802
3803bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003804 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003805}
3806
3807
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003808int JSFunction::NumberOfLiterals() {
3809 return literals()->length();
3810}
3811
3812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003814 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003815 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003816}
3817
3818
3819void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3820 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003821 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003822 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3823 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3824}
3825
3826
3827Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003828 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003829 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3830}
3831
3832
3833void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3834 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003835 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003836 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003837 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838}
3839
3840
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003841ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003842ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003843
3844
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003845ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3846ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3847
3848
3849ObjectHashTable* JSWeakMap::unchecked_table() {
3850 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3851}
3852
3853
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003854Address Foreign::address() {
3855 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003856}
3857
3858
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003859void Foreign::set_address(Address value) {
3860 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861}
3862
3863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003864ACCESSORS(JSValue, value, Object, kValueOffset)
3865
3866
3867JSValue* JSValue::cast(Object* obj) {
3868 ASSERT(obj->IsJSValue());
3869 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3870 return reinterpret_cast<JSValue*>(obj);
3871}
3872
3873
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003874ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3875ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3876ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3877ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3878ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3879SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3880SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3881
3882
3883JSMessageObject* JSMessageObject::cast(Object* obj) {
3884 ASSERT(obj->IsJSMessageObject());
3885 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3886 return reinterpret_cast<JSMessageObject*>(obj);
3887}
3888
3889
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003890INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003891ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003892ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003893ACCESSORS(Code, next_code_flushing_candidate,
3894 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895
3896
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003897byte* Code::instruction_start() {
3898 return FIELD_ADDR(this, kHeaderSize);
3899}
3900
3901
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003902byte* Code::instruction_end() {
3903 return instruction_start() + instruction_size();
3904}
3905
3906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003907int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003908 return RoundUp(instruction_size(), kObjectAlignment);
3909}
3910
3911
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003912FixedArray* Code::unchecked_deoptimization_data() {
3913 return reinterpret_cast<FixedArray*>(
3914 READ_FIELD(this, kDeoptimizationDataOffset));
3915}
3916
3917
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003918ByteArray* Code::unchecked_relocation_info() {
3919 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003920}
3921
3922
3923byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003924 return unchecked_relocation_info()->GetDataStartAddress();
3925}
3926
3927
3928int Code::relocation_size() {
3929 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003930}
3931
3932
3933byte* Code::entry() {
3934 return instruction_start();
3935}
3936
3937
3938bool Code::contains(byte* pc) {
3939 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003940 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003941}
3942
3943
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003944ACCESSORS(JSArray, length, Object, kLengthOffset)
3945
3946
ager@chromium.org236ad962008-09-25 09:45:57 +00003947ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003948
3949
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003950JSRegExp::Type JSRegExp::TypeTag() {
3951 Object* data = this->data();
3952 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3953 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3954 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003955}
3956
3957
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003958JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3959 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3960 return static_cast<JSRegExp::Type>(smi->value());
3961}
3962
3963
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003964int JSRegExp::CaptureCount() {
3965 switch (TypeTag()) {
3966 case ATOM:
3967 return 0;
3968 case IRREGEXP:
3969 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3970 default:
3971 UNREACHABLE();
3972 return -1;
3973 }
3974}
3975
3976
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003977JSRegExp::Flags JSRegExp::GetFlags() {
3978 ASSERT(this->data()->IsFixedArray());
3979 Object* data = this->data();
3980 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3981 return Flags(smi->value());
3982}
3983
3984
3985String* JSRegExp::Pattern() {
3986 ASSERT(this->data()->IsFixedArray());
3987 Object* data = this->data();
3988 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3989 return pattern;
3990}
3991
3992
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003993Object* JSRegExp::DataAt(int index) {
3994 ASSERT(TypeTag() != NOT_COMPILED);
3995 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003996}
3997
3998
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003999Object* JSRegExp::DataAtUnchecked(int index) {
4000 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4001 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4002 return READ_FIELD(fa, offset);
4003}
4004
4005
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004006void JSRegExp::SetDataAt(int index, Object* value) {
4007 ASSERT(TypeTag() != NOT_COMPILED);
4008 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4009 FixedArray::cast(data())->set(index, value);
4010}
4011
4012
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004013void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4014 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4015 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4016 if (value->IsSmi()) {
4017 fa->set_unchecked(index, Smi::cast(value));
4018 } else {
4019 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4020 }
4021}
4022
4023
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004024JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004025 ElementsKind kind = map()->elements_kind();
4026 ASSERT((kind == FAST_ELEMENTS &&
4027 (elements()->map() == GetHeap()->fixed_array_map() ||
4028 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004029 (kind == FAST_DOUBLE_ELEMENTS &&
4030 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004031 (kind == DICTIONARY_ELEMENTS &&
4032 elements()->IsFixedArray() &&
4033 elements()->IsDictionary()) ||
4034 (kind > DICTIONARY_ELEMENTS));
4035 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004036}
4037
4038
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004039ElementsAccessor* JSObject::GetElementsAccessor() {
4040 return ElementsAccessor::ForKind(GetElementsKind());
4041}
4042
4043
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004044bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004045 return GetElementsKind() == FAST_ELEMENTS;
4046}
4047
4048
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004049bool JSObject::HasFastDoubleElements() {
4050 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4051}
4052
4053
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004054bool JSObject::HasDictionaryElements() {
4055 return GetElementsKind() == DICTIONARY_ELEMENTS;
4056}
4057
4058
ager@chromium.org3811b432009-10-28 14:53:37 +00004059bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004060 HeapObject* array = elements();
4061 ASSERT(array != NULL);
4062 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004063}
4064
4065
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004066#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4067bool JSObject::HasExternal##name##Elements() { \
4068 HeapObject* array = elements(); \
4069 ASSERT(array != NULL); \
4070 if (!array->IsHeapObject()) \
4071 return false; \
4072 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004073}
4074
4075
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004076EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4077EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4078EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4079EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4080 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4081EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4082EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4083 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4084EXTERNAL_ELEMENTS_CHECK(Float,
4085 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004086EXTERNAL_ELEMENTS_CHECK(Double,
4087 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004088EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004089
4090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004091bool JSObject::HasNamedInterceptor() {
4092 return map()->has_named_interceptor();
4093}
4094
4095
4096bool JSObject::HasIndexedInterceptor() {
4097 return map()->has_indexed_interceptor();
4098}
4099
4100
ager@chromium.org5c838252010-02-19 08:53:10 +00004101bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004102 bool result = elements()->IsFixedArray() ||
4103 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004104 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004105 return result;
4106}
4107
4108
lrn@chromium.org303ada72010-10-27 09:33:13 +00004109MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004110 ASSERT(HasFastElements());
4111 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004112 Isolate* isolate = GetIsolate();
4113 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004114 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004115 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4116 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004117 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4118 return maybe_writable_elems;
4119 }
4120 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004121 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004122 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004123 return writable_elems;
4124}
4125
4126
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004127StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004128 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004129 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004130}
4131
4132
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004133NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004134 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004135 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004136}
4137
4138
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004139bool String::IsHashFieldComputed(uint32_t field) {
4140 return (field & kHashNotComputedMask) == 0;
4141}
4142
4143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004144bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004145 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004146}
4147
4148
4149uint32_t String::Hash() {
4150 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004151 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004152 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004153 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004154 return ComputeAndSetHash();
4155}
4156
4157
ager@chromium.org7c537e22008-10-16 08:43:32 +00004158StringHasher::StringHasher(int length)
4159 : length_(length),
4160 raw_running_hash_(0),
4161 array_index_(0),
4162 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4163 is_first_char_(true),
4164 is_valid_(true) { }
4165
4166
4167bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004168 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004169}
4170
4171
4172void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004173 // Use the Jenkins one-at-a-time hash function to update the hash
4174 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004175 raw_running_hash_ += c;
4176 raw_running_hash_ += (raw_running_hash_ << 10);
4177 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004178 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004179 if (is_array_index_) {
4180 if (c < '0' || c > '9') {
4181 is_array_index_ = false;
4182 } else {
4183 int d = c - '0';
4184 if (is_first_char_) {
4185 is_first_char_ = false;
4186 if (c == '0' && length_ > 1) {
4187 is_array_index_ = false;
4188 return;
4189 }
4190 }
4191 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4192 is_array_index_ = false;
4193 } else {
4194 array_index_ = array_index_ * 10 + d;
4195 }
4196 }
4197 }
4198}
4199
4200
4201void StringHasher::AddCharacterNoIndex(uc32 c) {
4202 ASSERT(!is_array_index());
4203 raw_running_hash_ += c;
4204 raw_running_hash_ += (raw_running_hash_ << 10);
4205 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4206}
4207
4208
4209uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004210 // Get the calculated raw hash value and do some more bit ops to distribute
4211 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004212 uint32_t result = raw_running_hash_;
4213 result += (result << 3);
4214 result ^= (result >> 11);
4215 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004216 if (result == 0) {
4217 result = 27;
4218 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004219 return result;
4220}
4221
4222
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004223template <typename schar>
4224uint32_t HashSequentialString(const schar* chars, int length) {
4225 StringHasher hasher(length);
4226 if (!hasher.has_trivial_hash()) {
4227 int i;
4228 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4229 hasher.AddCharacter(chars[i]);
4230 }
4231 for (; i < length; i++) {
4232 hasher.AddCharacterNoIndex(chars[i]);
4233 }
4234 }
4235 return hasher.GetHashField();
4236}
4237
4238
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004239bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004240 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004241 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4242 return false;
4243 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004244 return SlowAsArrayIndex(index);
4245}
4246
4247
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004248Object* JSReceiver::GetPrototype() {
4249 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004250}
4251
4252
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004253bool JSReceiver::HasProperty(String* name) {
4254 if (IsJSProxy()) {
4255 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4256 }
4257 return GetPropertyAttribute(name) != ABSENT;
4258}
4259
4260
4261bool JSReceiver::HasLocalProperty(String* name) {
4262 if (IsJSProxy()) {
4263 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4264 }
4265 return GetLocalPropertyAttribute(name) != ABSENT;
4266}
4267
4268
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004269PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270 return GetPropertyAttributeWithReceiver(this, key);
4271}
4272
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004273// TODO(504): this may be useful in other places too where JSGlobalProxy
4274// is used.
4275Object* JSObject::BypassGlobalProxy() {
4276 if (IsJSGlobalProxy()) {
4277 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004278 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004279 ASSERT(proto->IsJSGlobalObject());
4280 return proto;
4281 }
4282 return this;
4283}
4284
4285
4286bool JSObject::HasHiddenPropertiesObject() {
4287 ASSERT(!IsJSGlobalProxy());
4288 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004289 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004290 false) != ABSENT;
4291}
4292
4293
4294Object* JSObject::GetHiddenPropertiesObject() {
4295 ASSERT(!IsJSGlobalProxy());
4296 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004297 // You can't install a getter on a property indexed by the hidden symbol,
4298 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4299 // object.
4300 Object* result =
4301 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004302 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004303 &attributes)->ToObjectUnchecked();
4304 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004305}
4306
4307
lrn@chromium.org303ada72010-10-27 09:33:13 +00004308MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004309 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004310 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004311 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004312 DONT_ENUM,
4313 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004314}
4315
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004316
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004317bool JSObject::HasHiddenProperties() {
4318 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4319}
4320
4321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004322bool JSObject::HasElement(uint32_t index) {
4323 return HasElementWithReceiver(this, index);
4324}
4325
4326
4327bool AccessorInfo::all_can_read() {
4328 return BooleanBit::get(flag(), kAllCanReadBit);
4329}
4330
4331
4332void AccessorInfo::set_all_can_read(bool value) {
4333 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4334}
4335
4336
4337bool AccessorInfo::all_can_write() {
4338 return BooleanBit::get(flag(), kAllCanWriteBit);
4339}
4340
4341
4342void AccessorInfo::set_all_can_write(bool value) {
4343 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4344}
4345
4346
ager@chromium.org870a0b62008-11-04 11:43:05 +00004347bool AccessorInfo::prohibits_overwriting() {
4348 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4349}
4350
4351
4352void AccessorInfo::set_prohibits_overwriting(bool value) {
4353 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4354}
4355
4356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004357PropertyAttributes AccessorInfo::property_attributes() {
4358 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4359}
4360
4361
4362void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4363 ASSERT(AttributesField::is_valid(attributes));
4364 int rest_value = flag()->value() & ~AttributesField::mask();
4365 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4366}
4367
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004368
4369template<typename Shape, typename Key>
4370void Dictionary<Shape, Key>::SetEntry(int entry,
4371 Object* key,
4372 Object* value) {
4373 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4374}
4375
4376
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004377template<typename Shape, typename Key>
4378void Dictionary<Shape, Key>::SetEntry(int entry,
4379 Object* key,
4380 Object* value,
4381 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004382 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004383 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004384 AssertNoAllocation no_gc;
4385 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004386 FixedArray::set(index, key, mode);
4387 FixedArray::set(index+1, value, mode);
4388 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389}
4390
4391
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004392bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4393 ASSERT(other->IsNumber());
4394 return key == static_cast<uint32_t>(other->Number());
4395}
4396
4397
4398uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4399 return ComputeIntegerHash(key);
4400}
4401
4402
4403uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4404 ASSERT(other->IsNumber());
4405 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4406}
4407
4408
4409MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4410 return Isolate::Current()->heap()->NumberFromUint32(key);
4411}
4412
4413
4414bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4415 // We know that all entries in a hash table had their hash keys created.
4416 // Use that knowledge to have fast failure.
4417 if (key->Hash() != String::cast(other)->Hash()) return false;
4418 return key->Equals(String::cast(other));
4419}
4420
4421
4422uint32_t StringDictionaryShape::Hash(String* key) {
4423 return key->Hash();
4424}
4425
4426
4427uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4428 return String::cast(other)->Hash();
4429}
4430
4431
4432MaybeObject* StringDictionaryShape::AsObject(String* key) {
4433 return key;
4434}
4435
4436
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004437bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4438 return key == JSObject::cast(other);
4439}
4440
4441
4442uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4443 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4444 ASSERT(!maybe_hash->IsFailure());
4445 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4446}
4447
4448
4449uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4450 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4451 JSObject::OMIT_CREATION);
4452 ASSERT(!maybe_hash->IsFailure());
4453 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4454}
4455
4456
4457MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4458 return key;
4459}
4460
4461
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004462void ObjectHashTable::RemoveEntry(int entry) {
4463 RemoveEntry(entry, GetHeap());
4464}
4465
4466
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004467void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004468 // No write barrier is needed since empty_fixed_array is not in new space.
4469 // Please note this function is used during marking:
4470 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004471 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4472 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004473}
4474
4475
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004476void JSArray::EnsureSize(int required_size) {
4477 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004478 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004479 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4480 if (elts->length() < required_size) {
4481 // Doubling in size would be overkill, but leave some slack to avoid
4482 // constantly growing.
4483 Expand(required_size + (required_size >> 3));
4484 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004485 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004486 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4487 // Expand will allocate a new backing store in new space even if the size
4488 // we asked for isn't larger than what we had before.
4489 Expand(required_size);
4490 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004491}
4492
4493
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004494void JSArray::set_length(Smi* length) {
4495 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4496}
4497
4498
ager@chromium.org7c537e22008-10-16 08:43:32 +00004499void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004500 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004501 set_elements(storage);
4502}
4503
4504
lrn@chromium.org303ada72010-10-27 09:33:13 +00004505MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004506 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004507 return GetHeap()->CopyFixedArray(this);
4508}
4509
4510
4511Relocatable::Relocatable(Isolate* isolate) {
4512 ASSERT(isolate == Isolate::Current());
4513 isolate_ = isolate;
4514 prev_ = isolate->relocatable_top();
4515 isolate->set_relocatable_top(this);
4516}
4517
4518
4519Relocatable::~Relocatable() {
4520 ASSERT(isolate_ == Isolate::Current());
4521 ASSERT_EQ(isolate_->relocatable_top(), this);
4522 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004523}
4524
4525
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004526int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4527 return map->instance_size();
4528}
4529
4530
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004531void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004532 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004533 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004534}
4535
4536
4537template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004538void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004539 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004540 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004541}
4542
4543
4544void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4545 typedef v8::String::ExternalAsciiStringResource Resource;
4546 v->VisitExternalAsciiString(
4547 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4548}
4549
4550
4551template<typename StaticVisitor>
4552void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4553 typedef v8::String::ExternalAsciiStringResource Resource;
4554 StaticVisitor::VisitExternalAsciiString(
4555 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4556}
4557
4558
4559void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4560 typedef v8::String::ExternalStringResource Resource;
4561 v->VisitExternalTwoByteString(
4562 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4563}
4564
4565
4566template<typename StaticVisitor>
4567void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4568 typedef v8::String::ExternalStringResource Resource;
4569 StaticVisitor::VisitExternalTwoByteString(
4570 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4571}
4572
4573#define SLOT_ADDR(obj, offset) \
4574 reinterpret_cast<Object**>((obj)->address() + offset)
4575
4576template<int start_offset, int end_offset, int size>
4577void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4578 HeapObject* obj,
4579 ObjectVisitor* v) {
4580 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4581}
4582
4583
4584template<int start_offset>
4585void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4586 int object_size,
4587 ObjectVisitor* v) {
4588 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4589}
4590
4591#undef SLOT_ADDR
4592
4593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004594#undef CAST_ACCESSOR
4595#undef INT_ACCESSORS
4596#undef SMI_ACCESSORS
4597#undef ACCESSORS
4598#undef FIELD_ADDR
4599#undef READ_FIELD
4600#undef WRITE_FIELD
4601#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004602#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004603#undef READ_MEMADDR_FIELD
4604#undef WRITE_MEMADDR_FIELD
4605#undef READ_DOUBLE_FIELD
4606#undef WRITE_DOUBLE_FIELD
4607#undef READ_INT_FIELD
4608#undef WRITE_INT_FIELD
4609#undef READ_SHORT_FIELD
4610#undef WRITE_SHORT_FIELD
4611#undef READ_BYTE_FIELD
4612#undef WRITE_BYTE_FIELD
4613
4614
4615} } // namespace v8::internal
4616
4617#endif // V8_OBJECTS_INL_H_