blob: 098bd7a5c7b7f81db8d7814d9e9a3b6df820ad45 [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
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000300uint32_t StringShape::encoding_tag() {
301 return type_ & kStringEncodingMask;
302}
303
304
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305uint32_t StringShape::full_representation_tag() {
306 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
307}
308
309
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000310STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
311 Internals::kFullStringRepresentationMask);
312
313
ager@chromium.org870a0b62008-11-04 11:43:05 +0000314bool StringShape::IsSequentialAscii() {
315 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
316}
317
318
319bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000320 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000321}
322
323
324bool StringShape::IsExternalAscii() {
325 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
326}
327
328
329bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000330 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000331}
332
333
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000334STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
335 Internals::kExternalTwoByteRepresentationTag);
336
337
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000338uc32 FlatStringReader::Get(int index) {
339 ASSERT(0 <= index && index <= length_);
340 if (is_ascii_) {
341 return static_cast<const byte*>(start_)[index];
342 } else {
343 return static_cast<const uc16*>(start_)[index];
344 }
345}
346
347
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000348bool Object::IsNumber() {
349 return IsSmi() || IsHeapNumber();
350}
351
352
353bool Object::IsByteArray() {
354 return Object::IsHeapObject()
355 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
356}
357
358
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000359bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000360 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000361 HeapObject::cast(this)->map()->instance_type() ==
362 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000363}
364
365
ager@chromium.org3811b432009-10-28 14:53:37 +0000366bool Object::IsExternalArray() {
367 if (!Object::IsHeapObject())
368 return false;
369 InstanceType instance_type =
370 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000371 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
372 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000373}
374
375
376bool Object::IsExternalByteArray() {
377 return Object::IsHeapObject() &&
378 HeapObject::cast(this)->map()->instance_type() ==
379 EXTERNAL_BYTE_ARRAY_TYPE;
380}
381
382
383bool Object::IsExternalUnsignedByteArray() {
384 return Object::IsHeapObject() &&
385 HeapObject::cast(this)->map()->instance_type() ==
386 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
387}
388
389
390bool Object::IsExternalShortArray() {
391 return Object::IsHeapObject() &&
392 HeapObject::cast(this)->map()->instance_type() ==
393 EXTERNAL_SHORT_ARRAY_TYPE;
394}
395
396
397bool Object::IsExternalUnsignedShortArray() {
398 return Object::IsHeapObject() &&
399 HeapObject::cast(this)->map()->instance_type() ==
400 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
401}
402
403
404bool Object::IsExternalIntArray() {
405 return Object::IsHeapObject() &&
406 HeapObject::cast(this)->map()->instance_type() ==
407 EXTERNAL_INT_ARRAY_TYPE;
408}
409
410
411bool Object::IsExternalUnsignedIntArray() {
412 return Object::IsHeapObject() &&
413 HeapObject::cast(this)->map()->instance_type() ==
414 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
415}
416
417
418bool Object::IsExternalFloatArray() {
419 return Object::IsHeapObject() &&
420 HeapObject::cast(this)->map()->instance_type() ==
421 EXTERNAL_FLOAT_ARRAY_TYPE;
422}
423
424
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000425bool Object::IsExternalDoubleArray() {
426 return Object::IsHeapObject() &&
427 HeapObject::cast(this)->map()->instance_type() ==
428 EXTERNAL_DOUBLE_ARRAY_TYPE;
429}
430
431
lrn@chromium.org303ada72010-10-27 09:33:13 +0000432bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433 return HAS_FAILURE_TAG(this);
434}
435
436
lrn@chromium.org303ada72010-10-27 09:33:13 +0000437bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000438 return HAS_FAILURE_TAG(this)
439 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
440}
441
442
lrn@chromium.org303ada72010-10-27 09:33:13 +0000443bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000444 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000445 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000446}
447
448
lrn@chromium.org303ada72010-10-27 09:33:13 +0000449bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000450 return this == Failure::Exception();
451}
452
453
lrn@chromium.org303ada72010-10-27 09:33:13 +0000454bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000455 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000456}
457
458
459Failure* Failure::cast(MaybeObject* obj) {
460 ASSERT(HAS_FAILURE_TAG(obj));
461 return reinterpret_cast<Failure*>(obj);
462}
463
464
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000465bool Object::IsJSReceiver() {
466 return IsHeapObject() &&
467 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
468}
469
470
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000472 return IsJSReceiver() && !IsJSProxy();
473}
474
475
476bool Object::IsJSProxy() {
477 return Object::IsHeapObject() &&
478 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
479 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
480}
481
482
483bool Object::IsJSFunctionProxy() {
484 return Object::IsHeapObject() &&
485 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000486}
487
488
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000489bool Object::IsJSWeakMap() {
490 return Object::IsJSObject() &&
491 HeapObject::cast(this)->map()->instance_type() == JS_WEAK_MAP_TYPE;
492}
493
494
ager@chromium.org32912102009-01-16 10:38:43 +0000495bool Object::IsJSContextExtensionObject() {
496 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000497 && (HeapObject::cast(this)->map()->instance_type() ==
498 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000499}
500
501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502bool Object::IsMap() {
503 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000504 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000505}
506
507
508bool Object::IsFixedArray() {
509 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000510 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000511}
512
513
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000514bool Object::IsFixedDoubleArray() {
515 return Object::IsHeapObject()
516 && HeapObject::cast(this)->map()->instance_type() ==
517 FIXED_DOUBLE_ARRAY_TYPE;
518}
519
520
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000521bool Object::IsDescriptorArray() {
522 return IsFixedArray();
523}
524
525
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000526bool Object::IsDeoptimizationInputData() {
527 // Must be a fixed array.
528 if (!IsFixedArray()) return false;
529
530 // There's no sure way to detect the difference between a fixed array and
531 // a deoptimization data array. Since this is used for asserts we can
532 // check that the length is zero or else the fixed size plus a multiple of
533 // the entry size.
534 int length = FixedArray::cast(this)->length();
535 if (length == 0) return true;
536
537 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
538 return length >= 0 &&
539 length % DeoptimizationInputData::kDeoptEntrySize == 0;
540}
541
542
543bool Object::IsDeoptimizationOutputData() {
544 if (!IsFixedArray()) return false;
545 // There's actually no way to see the difference between a fixed array and
546 // a deoptimization data array. Since this is used for asserts we can check
547 // that the length is plausible though.
548 if (FixedArray::cast(this)->length() % 2 != 0) return false;
549 return true;
550}
551
552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000553bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000554 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000555 Map* map = HeapObject::cast(this)->map();
556 Heap* heap = map->GetHeap();
557 return (map == heap->function_context_map() ||
558 map == heap->catch_context_map() ||
559 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000560 map == heap->global_context_map() ||
561 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000562 }
563 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564}
565
566
567bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000568 return Object::IsHeapObject() &&
569 HeapObject::cast(this)->map() ==
570 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571}
572
573
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000574bool Object::IsSerializedScopeInfo() {
575 return Object::IsHeapObject() &&
576 HeapObject::cast(this)->map() ==
577 HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
578}
579
580
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000581bool Object::IsJSFunction() {
582 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000583 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000584}
585
586
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000587template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588 return obj->IsJSFunction();
589}
590
591
592bool Object::IsCode() {
593 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000594 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595}
596
597
598bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000599 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000600 return Object::IsHeapObject()
601 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
602}
603
604
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000605bool Object::IsJSGlobalPropertyCell() {
606 return Object::IsHeapObject()
607 && HeapObject::cast(this)->map()->instance_type()
608 == JS_GLOBAL_PROPERTY_CELL_TYPE;
609}
610
611
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612bool Object::IsSharedFunctionInfo() {
613 return Object::IsHeapObject() &&
614 (HeapObject::cast(this)->map()->instance_type() ==
615 SHARED_FUNCTION_INFO_TYPE);
616}
617
618
619bool Object::IsJSValue() {
620 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000621 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
622}
623
624
625bool Object::IsJSMessageObject() {
626 return Object::IsHeapObject()
627 && (HeapObject::cast(this)->map()->instance_type() ==
628 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000629}
630
631
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000632bool Object::IsStringWrapper() {
633 return IsJSValue() && JSValue::cast(this)->value()->IsString();
634}
635
636
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000637bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000639 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
643bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000644 return IsOddball() &&
645 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000646}
647
648
649bool Object::IsJSArray() {
650 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000651 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000652}
653
654
ager@chromium.org236ad962008-09-25 09:45:57 +0000655bool Object::IsJSRegExp() {
656 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000657 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000658}
659
660
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000661template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662 return obj->IsJSArray();
663}
664
665
666bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000667 return Object::IsHeapObject() &&
668 HeapObject::cast(this)->map() ==
669 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670}
671
672
673bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000674 return IsHashTable() &&
675 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000676}
677
678
679bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000680 return IsHashTable() && this ==
681 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000682}
683
684
ager@chromium.orgac091b72010-05-05 07:34:42 +0000685bool Object::IsJSFunctionResultCache() {
686 if (!IsFixedArray()) return false;
687 FixedArray* self = FixedArray::cast(this);
688 int length = self->length();
689 if (length < JSFunctionResultCache::kEntriesIndex) return false;
690 if ((length - JSFunctionResultCache::kEntriesIndex)
691 % JSFunctionResultCache::kEntrySize != 0) {
692 return false;
693 }
694#ifdef DEBUG
695 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
696#endif
697 return true;
698}
699
700
ricow@chromium.org65fae842010-08-25 15:26:24 +0000701bool Object::IsNormalizedMapCache() {
702 if (!IsFixedArray()) return false;
703 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
704 return false;
705 }
706#ifdef DEBUG
707 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
708#endif
709 return true;
710}
711
712
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000713bool Object::IsCompilationCacheTable() {
714 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000715}
716
717
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000718bool Object::IsCodeCacheHashTable() {
719 return IsHashTable();
720}
721
722
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000723bool Object::IsPolymorphicCodeCacheHashTable() {
724 return IsHashTable();
725}
726
727
ager@chromium.org236ad962008-09-25 09:45:57 +0000728bool Object::IsMapCache() {
729 return IsHashTable();
730}
731
732
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733bool Object::IsPrimitive() {
734 return IsOddball() || IsNumber() || IsString();
735}
736
737
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738bool Object::IsJSGlobalProxy() {
739 bool result = IsHeapObject() &&
740 (HeapObject::cast(this)->map()->instance_type() ==
741 JS_GLOBAL_PROXY_TYPE);
742 ASSERT(!result || IsAccessCheckNeeded());
743 return result;
744}
745
746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000747bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000748 if (!IsHeapObject()) return false;
749
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000750 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000751 return type == JS_GLOBAL_OBJECT_TYPE ||
752 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753}
754
755
756bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757 return IsHeapObject() &&
758 (HeapObject::cast(this)->map()->instance_type() ==
759 JS_GLOBAL_OBJECT_TYPE);
760}
761
762
763bool Object::IsJSBuiltinsObject() {
764 return IsHeapObject() &&
765 (HeapObject::cast(this)->map()->instance_type() ==
766 JS_BUILTINS_OBJECT_TYPE);
767}
768
769
770bool Object::IsUndetectableObject() {
771 return IsHeapObject()
772 && HeapObject::cast(this)->map()->is_undetectable();
773}
774
775
776bool Object::IsAccessCheckNeeded() {
777 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000778 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779}
780
781
782bool Object::IsStruct() {
783 if (!IsHeapObject()) return false;
784 switch (HeapObject::cast(this)->map()->instance_type()) {
785#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
786 STRUCT_LIST(MAKE_STRUCT_CASE)
787#undef MAKE_STRUCT_CASE
788 default: return false;
789 }
790}
791
792
793#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
794 bool Object::Is##Name() { \
795 return Object::IsHeapObject() \
796 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
797 }
798 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
799#undef MAKE_STRUCT_PREDICATE
800
801
802bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000807bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000808 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
809}
810
811
812bool Object::IsTheHole() {
813 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814}
815
816
817bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000818 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819}
820
821
822bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000823 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000824}
825
826
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000827bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000828 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000829}
830
831
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000832double Object::Number() {
833 ASSERT(IsNumber());
834 return IsSmi()
835 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
836 : reinterpret_cast<HeapNumber*>(this)->value();
837}
838
839
lrn@chromium.org303ada72010-10-27 09:33:13 +0000840MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000841 if (IsSmi()) return this;
842 if (IsHeapNumber()) {
843 double value = HeapNumber::cast(this)->value();
844 int int_value = FastD2I(value);
845 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
846 return Smi::FromInt(int_value);
847 }
848 }
849 return Failure::Exception();
850}
851
852
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000853bool Object::HasSpecificClassOf(String* name) {
854 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
855}
856
857
lrn@chromium.org303ada72010-10-27 09:33:13 +0000858MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000859 // GetElement can trigger a getter which can cause allocation.
860 // This was not always the case. This ASSERT is here to catch
861 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000862 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000863 return GetElementWithReceiver(this, index);
864}
865
866
lrn@chromium.org303ada72010-10-27 09:33:13 +0000867Object* Object::GetElementNoExceptionThrown(uint32_t index) {
868 MaybeObject* maybe = GetElementWithReceiver(this, index);
869 ASSERT(!maybe->IsFailure());
870 Object* result = NULL; // Initialization to please compiler.
871 maybe->ToObject(&result);
872 return result;
873}
874
875
876MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877 PropertyAttributes attributes;
878 return GetPropertyWithReceiver(this, key, &attributes);
879}
880
881
lrn@chromium.org303ada72010-10-27 09:33:13 +0000882MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883 return GetPropertyWithReceiver(this, key, attributes);
884}
885
886
887#define FIELD_ADDR(p, offset) \
888 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
889
890#define READ_FIELD(p, offset) \
891 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
892
893#define WRITE_FIELD(p, offset, value) \
894 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
895
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000896// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000898 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000899
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000900// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000901// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000902#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000903 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000904 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000905 } else { \
906 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000907 ASSERT(heap->InNewSpace(object) || \
908 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000909 Page::FromAddress(object->address())-> \
910 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000911 }
912
lrn@chromium.org7516f052011-03-30 08:52:27 +0000913#ifndef V8_TARGET_ARCH_MIPS
914 #define READ_DOUBLE_FIELD(p, offset) \
915 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
916#else // V8_TARGET_ARCH_MIPS
917 // Prevent gcc from using load-double (mips ldc1) on (possibly)
918 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000919 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000920 union conversion {
921 double d;
922 uint32_t u[2];
923 } c;
924 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
925 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
926 return c.d;
927 }
928 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
929#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930
lrn@chromium.org7516f052011-03-30 08:52:27 +0000931
932#ifndef V8_TARGET_ARCH_MIPS
933 #define WRITE_DOUBLE_FIELD(p, offset, value) \
934 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
935#else // V8_TARGET_ARCH_MIPS
936 // Prevent gcc from using store-double (mips sdc1) on (possibly)
937 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000938 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000939 double value) {
940 union conversion {
941 double d;
942 uint32_t u[2];
943 } c;
944 c.d = value;
945 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
946 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
947 }
948 #define WRITE_DOUBLE_FIELD(p, offset, value) \
949 write_double_field(p, offset, value)
950#endif // V8_TARGET_ARCH_MIPS
951
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952
953#define READ_INT_FIELD(p, offset) \
954 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
955
956#define WRITE_INT_FIELD(p, offset, value) \
957 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
958
ager@chromium.org3e875802009-06-29 08:26:34 +0000959#define READ_INTPTR_FIELD(p, offset) \
960 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
961
962#define WRITE_INTPTR_FIELD(p, offset, value) \
963 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
964
ager@chromium.org7c537e22008-10-16 08:43:32 +0000965#define READ_UINT32_FIELD(p, offset) \
966 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
967
968#define WRITE_UINT32_FIELD(p, offset, value) \
969 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000971#define READ_SHORT_FIELD(p, offset) \
972 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
973
974#define WRITE_SHORT_FIELD(p, offset, value) \
975 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
976
977#define READ_BYTE_FIELD(p, offset) \
978 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
979
980#define WRITE_BYTE_FIELD(p, offset, value) \
981 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
982
983
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000984Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
985 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986}
987
988
989int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000990 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000991}
992
993
994Smi* Smi::FromInt(int value) {
995 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000996 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000997 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000999 return reinterpret_cast<Smi*>(tagged_value);
1000}
1001
1002
1003Smi* Smi::FromIntptr(intptr_t value) {
1004 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001005 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1006 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001007}
1008
1009
1010Failure::Type Failure::type() const {
1011 return static_cast<Type>(value() & kFailureTypeTagMask);
1012}
1013
1014
1015bool Failure::IsInternalError() const {
1016 return type() == INTERNAL_ERROR;
1017}
1018
1019
1020bool Failure::IsOutOfMemoryException() const {
1021 return type() == OUT_OF_MEMORY_EXCEPTION;
1022}
1023
1024
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001025AllocationSpace Failure::allocation_space() const {
1026 ASSERT_EQ(RETRY_AFTER_GC, type());
1027 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1028 & kSpaceTagMask);
1029}
1030
1031
1032Failure* Failure::InternalError() {
1033 return Construct(INTERNAL_ERROR);
1034}
1035
1036
1037Failure* Failure::Exception() {
1038 return Construct(EXCEPTION);
1039}
1040
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001041
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042Failure* Failure::OutOfMemoryException() {
1043 return Construct(OUT_OF_MEMORY_EXCEPTION);
1044}
1045
1046
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001047intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001048 return static_cast<intptr_t>(
1049 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001050}
1051
1052
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001053Failure* Failure::RetryAfterGC() {
1054 return RetryAfterGC(NEW_SPACE);
1055}
1056
1057
1058Failure* Failure::RetryAfterGC(AllocationSpace space) {
1059 ASSERT((space & ~kSpaceTagMask) == 0);
1060 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001061}
1062
1063
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001064Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001065 uintptr_t info =
1066 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001067 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001068 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001069}
1070
1071
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001072bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001073#ifdef DEBUG
1074 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1075#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001076
1077#ifdef V8_TARGET_ARCH_X64
1078 // To be representable as a long smi, the value must be a 32-bit integer.
1079 bool result = (value == static_cast<int32_t>(value));
1080#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001081 // To be representable as an tagged small integer, the two
1082 // most-significant bits of 'value' must be either 00 or 11 due to
1083 // sign-extension. To check this we add 01 to the two
1084 // most-significant bits, and check if the most-significant bit is 0
1085 //
1086 // CAUTION: The original code below:
1087 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1088 // may lead to incorrect results according to the C language spec, and
1089 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1090 // compiler may produce undefined results in case of signed integer
1091 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001092 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001093#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001094 ASSERT(result == in_range);
1095 return result;
1096}
1097
1098
kasper.lund7276f142008-07-30 08:49:36 +00001099MapWord MapWord::FromMap(Map* map) {
1100 return MapWord(reinterpret_cast<uintptr_t>(map));
1101}
1102
1103
1104Map* MapWord::ToMap() {
1105 return reinterpret_cast<Map*>(value_);
1106}
1107
1108
1109bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001110 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001111}
1112
1113
1114MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001115 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1116 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001117}
1118
1119
1120HeapObject* MapWord::ToForwardingAddress() {
1121 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001122 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001123}
1124
1125
1126bool MapWord::IsMarked() {
1127 return (value_ & kMarkingMask) == 0;
1128}
1129
1130
1131void MapWord::SetMark() {
1132 value_ &= ~kMarkingMask;
1133}
1134
1135
1136void MapWord::ClearMark() {
1137 value_ |= kMarkingMask;
1138}
1139
1140
1141bool MapWord::IsOverflowed() {
1142 return (value_ & kOverflowMask) != 0;
1143}
1144
1145
1146void MapWord::SetOverflow() {
1147 value_ |= kOverflowMask;
1148}
1149
1150
1151void MapWord::ClearOverflow() {
1152 value_ &= ~kOverflowMask;
1153}
1154
1155
1156MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1157 // Offset is the distance in live bytes from the first live object in the
1158 // same page. The offset between two objects in the same page should not
1159 // exceed the object area size of a page.
1160 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1161
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001162 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001163 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1164
1165 Page* map_page = Page::FromAddress(map_address);
1166 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1167
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001168 uintptr_t map_page_offset =
1169 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001170
1171 uintptr_t encoding =
1172 (compact_offset << kForwardingOffsetShift) |
1173 (map_page_offset << kMapPageOffsetShift) |
1174 (map_page->mc_page_index << kMapPageIndexShift);
1175 return MapWord(encoding);
1176}
1177
1178
1179Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001180 int map_page_index =
1181 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001182 ASSERT_MAP_PAGE_INDEX(map_page_index);
1183
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001184 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001185 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1186 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001187
1188 return (map_space->PageAddress(map_page_index) + map_page_offset);
1189}
1190
1191
1192int MapWord::DecodeOffset() {
1193 // The offset field is represented in the kForwardingOffsetBits
1194 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001195 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1196 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1197 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001198}
1199
1200
1201MapWord MapWord::FromEncodedAddress(Address address) {
1202 return MapWord(reinterpret_cast<uintptr_t>(address));
1203}
1204
1205
1206Address MapWord::ToEncodedAddress() {
1207 return reinterpret_cast<Address>(value_);
1208}
1209
1210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211#ifdef DEBUG
1212void HeapObject::VerifyObjectField(int offset) {
1213 VerifyPointer(READ_FIELD(this, offset));
1214}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001215
1216void HeapObject::VerifySmiField(int offset) {
1217 ASSERT(READ_FIELD(this, offset)->IsSmi());
1218}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219#endif
1220
1221
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001222Heap* HeapObject::GetHeap() {
1223 // During GC, the map pointer in HeapObject is used in various ways that
1224 // prevent us from retrieving Heap from the map.
1225 // Assert that we are not in GC, implement GC code in a way that it doesn't
1226 // pull heap from the map.
1227 ASSERT(HEAP->is_safe_to_read_maps());
1228 return map()->heap();
1229}
1230
1231
1232Isolate* HeapObject::GetIsolate() {
1233 return GetHeap()->isolate();
1234}
1235
1236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001238 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239}
1240
1241
1242void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001243 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244}
1245
1246
kasper.lund7276f142008-07-30 08:49:36 +00001247MapWord HeapObject::map_word() {
1248 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1249}
1250
1251
1252void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001253 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001254 // here.
1255 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1256}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001257
1258
1259HeapObject* HeapObject::FromAddress(Address address) {
1260 ASSERT_TAG_ALIGNED(address);
1261 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1262}
1263
1264
1265Address HeapObject::address() {
1266 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1267}
1268
1269
1270int HeapObject::Size() {
1271 return SizeFromMap(map());
1272}
1273
1274
1275void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1276 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1277 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1278}
1279
1280
1281void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1282 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1283}
1284
1285
kasper.lund7276f142008-07-30 08:49:36 +00001286bool HeapObject::IsMarked() {
1287 return map_word().IsMarked();
1288}
1289
1290
1291void HeapObject::SetMark() {
1292 ASSERT(!IsMarked());
1293 MapWord first_word = map_word();
1294 first_word.SetMark();
1295 set_map_word(first_word);
1296}
1297
1298
1299void HeapObject::ClearMark() {
1300 ASSERT(IsMarked());
1301 MapWord first_word = map_word();
1302 first_word.ClearMark();
1303 set_map_word(first_word);
1304}
1305
1306
1307bool HeapObject::IsOverflowed() {
1308 return map_word().IsOverflowed();
1309}
1310
1311
1312void HeapObject::SetOverflow() {
1313 MapWord first_word = map_word();
1314 first_word.SetOverflow();
1315 set_map_word(first_word);
1316}
1317
1318
1319void HeapObject::ClearOverflow() {
1320 ASSERT(IsOverflowed());
1321 MapWord first_word = map_word();
1322 first_word.ClearOverflow();
1323 set_map_word(first_word);
1324}
1325
1326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327double HeapNumber::value() {
1328 return READ_DOUBLE_FIELD(this, kValueOffset);
1329}
1330
1331
1332void HeapNumber::set_value(double value) {
1333 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1334}
1335
1336
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001337int HeapNumber::get_exponent() {
1338 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1339 kExponentShift) - kExponentBias;
1340}
1341
1342
1343int HeapNumber::get_sign() {
1344 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1345}
1346
1347
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001348ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001349
1350
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001351FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001352 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001353 ASSERT(array->HasValidElements());
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001354 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001355}
1356
1357
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001358void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001359 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001360 (value->map() == GetHeap()->fixed_array_map() ||
1361 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001362 ASSERT(map()->has_fast_double_elements() ==
1363 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001364 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001365 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001367}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368
1369
1370void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001371 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1372 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373}
1374
1375
1376void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001377 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001378 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1379 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380}
1381
1382
lrn@chromium.org303ada72010-10-27 09:33:13 +00001383MaybeObject* JSObject::ResetElements() {
1384 Object* obj;
1385 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1386 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1387 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001388 set_map(Map::cast(obj));
1389 initialize_elements();
1390 return this;
1391}
1392
1393
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394ACCESSORS(Oddball, to_string, String, kToStringOffset)
1395ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1396
1397
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001398byte Oddball::kind() {
1399 return READ_BYTE_FIELD(this, kKindOffset);
1400}
1401
1402
1403void Oddball::set_kind(byte value) {
1404 WRITE_BYTE_FIELD(this, kKindOffset, value);
1405}
1406
1407
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001408Object* JSGlobalPropertyCell::value() {
1409 return READ_FIELD(this, kValueOffset);
1410}
1411
1412
1413void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1414 // The write barrier is not used for global property cells.
1415 ASSERT(!val->IsJSGlobalPropertyCell());
1416 WRITE_FIELD(this, kValueOffset, val);
1417}
1418
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001421 InstanceType type = map()->instance_type();
1422 // Check for the most common kind of JavaScript object before
1423 // falling into the generic switch. This speeds up the internal
1424 // field operations considerably on average.
1425 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1426 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001427 case JS_GLOBAL_PROXY_TYPE:
1428 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001429 case JS_GLOBAL_OBJECT_TYPE:
1430 return JSGlobalObject::kSize;
1431 case JS_BUILTINS_OBJECT_TYPE:
1432 return JSBuiltinsObject::kSize;
1433 case JS_FUNCTION_TYPE:
1434 return JSFunction::kSize;
1435 case JS_VALUE_TYPE:
1436 return JSValue::kSize;
1437 case JS_ARRAY_TYPE:
1438 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001439 case JS_WEAK_MAP_TYPE:
1440 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001441 case JS_REGEXP_TYPE:
1442 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001443 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001445 case JS_MESSAGE_OBJECT_TYPE:
1446 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447 default:
1448 UNREACHABLE();
1449 return 0;
1450 }
1451}
1452
1453
1454int JSObject::GetInternalFieldCount() {
1455 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001456 // Make sure to adjust for the number of in-object properties. These
1457 // properties do contribute to the size, but are not internal fields.
1458 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1459 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460}
1461
1462
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001463int JSObject::GetInternalFieldOffset(int index) {
1464 ASSERT(index < GetInternalFieldCount() && index >= 0);
1465 return GetHeaderSize() + (kPointerSize * index);
1466}
1467
1468
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469Object* JSObject::GetInternalField(int index) {
1470 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001471 // Internal objects do follow immediately after the header, whereas in-object
1472 // properties are at the end of the object. Therefore there is no need
1473 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1475}
1476
1477
1478void JSObject::SetInternalField(int index, Object* value) {
1479 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001480 // Internal objects do follow immediately after the header, whereas in-object
1481 // properties are at the end of the object. Therefore there is no need
1482 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001483 int offset = GetHeaderSize() + (kPointerSize * index);
1484 WRITE_FIELD(this, offset, value);
1485 WRITE_BARRIER(this, offset);
1486}
1487
1488
ager@chromium.org7c537e22008-10-16 08:43:32 +00001489// Access fast-case object properties at index. The use of these routines
1490// is needed to correctly distinguish between properties stored in-object and
1491// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001492Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001493 // Adjust for the number of properties stored in the object.
1494 index -= map()->inobject_properties();
1495 if (index < 0) {
1496 int offset = map()->instance_size() + (index * kPointerSize);
1497 return READ_FIELD(this, offset);
1498 } else {
1499 ASSERT(index < properties()->length());
1500 return properties()->get(index);
1501 }
1502}
1503
1504
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001505Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 if (index < 0) {
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
1511 WRITE_BARRIER(this, offset);
1512 } else {
1513 ASSERT(index < properties()->length());
1514 properties()->set(index, value);
1515 }
1516 return value;
1517}
1518
1519
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520int JSObject::GetInObjectPropertyOffset(int index) {
1521 // Adjust for the number of properties stored in the object.
1522 index -= map()->inobject_properties();
1523 ASSERT(index < 0);
1524 return map()->instance_size() + (index * kPointerSize);
1525}
1526
1527
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001528Object* JSObject::InObjectPropertyAt(int index) {
1529 // Adjust for the number of properties stored in the object.
1530 index -= map()->inobject_properties();
1531 ASSERT(index < 0);
1532 int offset = map()->instance_size() + (index * kPointerSize);
1533 return READ_FIELD(this, offset);
1534}
1535
1536
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001537Object* JSObject::InObjectPropertyAtPut(int index,
1538 Object* value,
1539 WriteBarrierMode mode) {
1540 // Adjust for the number of properties stored in the object.
1541 index -= map()->inobject_properties();
1542 ASSERT(index < 0);
1543 int offset = map()->instance_size() + (index * kPointerSize);
1544 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001545 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001546 return value;
1547}
1548
1549
1550
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001551void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001552 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001554 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555 }
1556}
1557
1558
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001559bool JSObject::HasFastProperties() {
1560 return !properties()->IsDictionary();
1561}
1562
1563
1564int JSObject::MaxFastProperties() {
1565 // Allow extra fast properties if the object has more than
1566 // kMaxFastProperties in-object properties. When this is the case,
1567 // it is very unlikely that the object is being used as a dictionary
1568 // and there is a good chance that allowing more map transitions
1569 // will be worth it.
1570 return Max(map()->inobject_properties(), kMaxFastProperties);
1571}
1572
1573
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001574void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001575 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001576 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001577 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578 }
1579}
1580
1581
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001582bool Object::ToArrayIndex(uint32_t* index) {
1583 if (IsSmi()) {
1584 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585 if (value < 0) return false;
1586 *index = value;
1587 return true;
1588 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001589 if (IsHeapNumber()) {
1590 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591 uint32_t uint_value = static_cast<uint32_t>(value);
1592 if (value == static_cast<double>(uint_value)) {
1593 *index = uint_value;
1594 return true;
1595 }
1596 }
1597 return false;
1598}
1599
1600
1601bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1602 if (!this->IsJSValue()) return false;
1603
1604 JSValue* js_value = JSValue::cast(this);
1605 if (!js_value->value()->IsString()) return false;
1606
1607 String* str = String::cast(js_value->value());
1608 if (index >= (uint32_t)str->length()) return false;
1609
1610 return true;
1611}
1612
1613
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001614FixedArrayBase* FixedArrayBase::cast(Object* object) {
1615 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1616 return reinterpret_cast<FixedArrayBase*>(object);
1617}
1618
1619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620Object* FixedArray::get(int index) {
1621 ASSERT(index >= 0 && index < this->length());
1622 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1623}
1624
1625
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001626void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001627 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001628 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001629 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1630 int offset = kHeaderSize + index * kPointerSize;
1631 WRITE_FIELD(this, offset, value);
1632}
1633
1634
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001636 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 ASSERT(index >= 0 && index < this->length());
1638 int offset = kHeaderSize + index * kPointerSize;
1639 WRITE_FIELD(this, offset, value);
1640 WRITE_BARRIER(this, offset);
1641}
1642
1643
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001644inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1645 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1646}
1647
1648
1649inline double FixedDoubleArray::hole_nan_as_double() {
1650 return BitCast<double, uint64_t>(kHoleNanInt64);
1651}
1652
1653
1654inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1655 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1656 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1657 return OS::nan_value();
1658}
1659
1660
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001661double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001662 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1663 map() != HEAP->fixed_array_map());
1664 ASSERT(index >= 0 && index < this->length());
1665 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1666 ASSERT(!is_the_hole_nan(result));
1667 return result;
1668}
1669
1670
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001671MaybeObject* FixedDoubleArray::get(int index) {
1672 if (is_the_hole(index)) {
1673 return GetHeap()->the_hole_value();
1674 } else {
1675 return GetHeap()->NumberFromDouble(get_scalar(index));
1676 }
1677}
1678
1679
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001680void FixedDoubleArray::set(int index, double value) {
1681 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1682 map() != HEAP->fixed_array_map());
1683 int offset = kHeaderSize + index * kDoubleSize;
1684 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1685 WRITE_DOUBLE_FIELD(this, offset, value);
1686}
1687
1688
1689void FixedDoubleArray::set_the_hole(int index) {
1690 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1691 map() != HEAP->fixed_array_map());
1692 int offset = kHeaderSize + index * kDoubleSize;
1693 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1694}
1695
1696
1697bool FixedDoubleArray::is_the_hole(int index) {
1698 int offset = kHeaderSize + index * kDoubleSize;
1699 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1700}
1701
1702
1703void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1704 int old_length = from->length();
1705 ASSERT(old_length < length());
1706 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1707 FIELD_ADDR(from, kHeaderSize),
1708 old_length * kDoubleSize);
1709 int offset = kHeaderSize + old_length * kDoubleSize;
1710 for (int current = from->length(); current < length(); ++current) {
1711 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1712 offset += kDoubleSize;
1713 }
1714}
1715
1716
1717void FixedDoubleArray::Initialize(FixedArray* from) {
1718 int old_length = from->length();
1719 ASSERT(old_length < length());
1720 for (int i = 0; i < old_length; i++) {
1721 Object* hole_or_object = from->get(i);
1722 if (hole_or_object->IsTheHole()) {
1723 set_the_hole(i);
1724 } else {
1725 set(i, hole_or_object->Number());
1726 }
1727 }
1728 int offset = kHeaderSize + old_length * kDoubleSize;
1729 for (int current = from->length(); current < length(); ++current) {
1730 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1731 offset += kDoubleSize;
1732 }
1733}
1734
1735
1736void FixedDoubleArray::Initialize(NumberDictionary* from) {
1737 int offset = kHeaderSize;
1738 for (int current = 0; current < length(); ++current) {
1739 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1740 offset += kDoubleSize;
1741 }
1742 for (int i = 0; i < from->Capacity(); i++) {
1743 Object* key = from->KeyAt(i);
1744 if (key->IsNumber()) {
1745 uint32_t entry = static_cast<uint32_t>(key->Number());
1746 set(entry, from->ValueAt(i)->Number());
1747 }
1748 }
1749}
1750
1751
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001752WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001753 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 return UPDATE_WRITE_BARRIER;
1755}
1756
1757
1758void FixedArray::set(int index,
1759 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001760 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001761 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001762 ASSERT(index >= 0 && index < this->length());
1763 int offset = kHeaderSize + index * kPointerSize;
1764 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001765 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766}
1767
1768
1769void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001770 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001772 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001773 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1774}
1775
1776
1777void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001778 ASSERT(map() != HEAP->fixed_cow_array_map());
1779 set_undefined(GetHeap(), index);
1780}
1781
1782
1783void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001785 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001787 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001788}
1789
1790
ager@chromium.org236ad962008-09-25 09:45:57 +00001791void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001792 set_null(GetHeap(), index);
1793}
1794
1795
1796void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001797 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(!heap->InNewSpace(heap->null_value()));
1799 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001800}
1801
1802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001804 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001806 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1807 WRITE_FIELD(this,
1808 kHeaderSize + index * kPointerSize,
1809 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810}
1811
1812
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001813void FixedArray::set_unchecked(int index, Smi* value) {
1814 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1815 int offset = kHeaderSize + index * kPointerSize;
1816 WRITE_FIELD(this, offset, value);
1817}
1818
1819
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001820void FixedArray::set_unchecked(Heap* heap,
1821 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001822 Object* value,
1823 WriteBarrierMode mode) {
1824 int offset = kHeaderSize + index * kPointerSize;
1825 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001826 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001827}
1828
1829
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001831 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1833 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001834}
1835
1836
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001837Object** FixedArray::data_start() {
1838 return HeapObject::RawField(this, kHeaderSize);
1839}
1840
1841
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001842bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001843 ASSERT(this->IsSmi() ||
1844 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001845 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001846 return this->IsSmi() || length() <= kFirstIndex;
1847}
1848
1849
1850int DescriptorArray::bit_field3_storage() {
1851 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1852 return Smi::cast(storage)->value();
1853}
1854
1855void DescriptorArray::set_bit_field3_storage(int value) {
1856 ASSERT(!IsEmpty());
1857 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001858}
1859
1860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1862 Object* tmp = array->get(first);
1863 fast_set(array, first, array->get(second));
1864 fast_set(array, second, tmp);
1865}
1866
1867
1868int DescriptorArray::Search(String* name) {
1869 SLOW_ASSERT(IsSortedNoDuplicates());
1870
1871 // Check for empty descriptor array.
1872 int nof = number_of_descriptors();
1873 if (nof == 0) return kNotFound;
1874
1875 // Fast case: do linear search for small arrays.
1876 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001877 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001878 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001879 }
1880
1881 // Slow case: perform binary search.
1882 return BinarySearch(name, 0, nof - 1);
1883}
1884
1885
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001886int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001887 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001888 if (number == DescriptorLookupCache::kAbsent) {
1889 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001890 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001891 }
1892 return number;
1893}
1894
1895
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001896String* DescriptorArray::GetKey(int descriptor_number) {
1897 ASSERT(descriptor_number < number_of_descriptors());
1898 return String::cast(get(ToKeyIndex(descriptor_number)));
1899}
1900
1901
1902Object* DescriptorArray::GetValue(int descriptor_number) {
1903 ASSERT(descriptor_number < number_of_descriptors());
1904 return GetContentArray()->get(ToValueIndex(descriptor_number));
1905}
1906
1907
1908Smi* DescriptorArray::GetDetails(int descriptor_number) {
1909 ASSERT(descriptor_number < number_of_descriptors());
1910 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1911}
1912
1913
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001914PropertyType DescriptorArray::GetType(int descriptor_number) {
1915 ASSERT(descriptor_number < number_of_descriptors());
1916 return PropertyDetails(GetDetails(descriptor_number)).type();
1917}
1918
1919
1920int DescriptorArray::GetFieldIndex(int descriptor_number) {
1921 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1922}
1923
1924
1925JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1926 return JSFunction::cast(GetValue(descriptor_number));
1927}
1928
1929
1930Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1931 ASSERT(GetType(descriptor_number) == CALLBACKS);
1932 return GetValue(descriptor_number);
1933}
1934
1935
1936AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1937 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001938 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1939 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001940}
1941
1942
1943bool DescriptorArray::IsProperty(int descriptor_number) {
1944 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1945}
1946
1947
1948bool DescriptorArray::IsTransition(int descriptor_number) {
1949 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001950 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1951 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001952}
1953
1954
1955bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1956 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1957}
1958
1959
1960bool DescriptorArray::IsDontEnum(int descriptor_number) {
1961 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1962}
1963
1964
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1966 desc->Init(GetKey(descriptor_number),
1967 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001968 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001969}
1970
1971
1972void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1973 // Range check.
1974 ASSERT(descriptor_number < number_of_descriptors());
1975
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001976 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001977 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1978 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001979
1980 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1981 FixedArray* content_array = GetContentArray();
1982 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1983 fast_set(content_array, ToDetailsIndex(descriptor_number),
1984 desc->GetDetails().AsSmi());
1985}
1986
1987
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001988void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1989 Descriptor desc;
1990 src->Get(src_index, &desc);
1991 Set(index, &desc);
1992}
1993
1994
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995void DescriptorArray::Swap(int first, int second) {
1996 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1997 FixedArray* content_array = GetContentArray();
1998 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1999 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
2000}
2001
2002
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002003template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002004int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2005 const int kMinCapacity = 32;
2006 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2007 if (capacity < kMinCapacity) {
2008 capacity = kMinCapacity; // Guarantee min capacity.
2009 }
2010 return capacity;
2011}
2012
2013
2014template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002015int HashTable<Shape, Key>::FindEntry(Key key) {
2016 return FindEntry(GetIsolate(), key);
2017}
2018
2019
2020// Find entry for key otherwise return kNotFound.
2021template<typename Shape, typename Key>
2022int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2023 uint32_t capacity = Capacity();
2024 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2025 uint32_t count = 1;
2026 // EnsureCapacity will guarantee the hash table is never full.
2027 while (true) {
2028 Object* element = KeyAt(entry);
2029 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2030 if (element != isolate->heap()->null_value() &&
2031 Shape::IsMatch(key, element)) return entry;
2032 entry = NextProbe(entry, count++, capacity);
2033 }
2034 return kNotFound;
2035}
2036
2037
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002038bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002039 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040 if (!max_index_object->IsSmi()) return false;
2041 return 0 !=
2042 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2043}
2044
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002045uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002047 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048 if (!max_index_object->IsSmi()) return 0;
2049 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2050 return value >> kRequiresSlowElementsTagSize;
2051}
2052
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002053void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002054 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002055}
2056
2057
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058// ------------------------------------
2059// Cast operations
2060
2061
2062CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002063CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002065CAST_ACCESSOR(DeoptimizationInputData)
2066CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002067CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002068CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002069CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002070CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002071CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002072CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002073CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002074CAST_ACCESSOR(String)
2075CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002076CAST_ACCESSOR(SeqAsciiString)
2077CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002078CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002079CAST_ACCESSOR(ExternalString)
2080CAST_ACCESSOR(ExternalAsciiString)
2081CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002082CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083CAST_ACCESSOR(JSObject)
2084CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085CAST_ACCESSOR(HeapObject)
2086CAST_ACCESSOR(HeapNumber)
2087CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002088CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089CAST_ACCESSOR(SharedFunctionInfo)
2090CAST_ACCESSOR(Map)
2091CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002092CAST_ACCESSOR(GlobalObject)
2093CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094CAST_ACCESSOR(JSGlobalObject)
2095CAST_ACCESSOR(JSBuiltinsObject)
2096CAST_ACCESSOR(Code)
2097CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002098CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002099CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002100CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002101CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002102CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002103CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002104CAST_ACCESSOR(ExternalArray)
2105CAST_ACCESSOR(ExternalByteArray)
2106CAST_ACCESSOR(ExternalUnsignedByteArray)
2107CAST_ACCESSOR(ExternalShortArray)
2108CAST_ACCESSOR(ExternalUnsignedShortArray)
2109CAST_ACCESSOR(ExternalIntArray)
2110CAST_ACCESSOR(ExternalUnsignedIntArray)
2111CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002112CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002113CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114CAST_ACCESSOR(Struct)
2115
2116
2117#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2118 STRUCT_LIST(MAKE_STRUCT_CAST)
2119#undef MAKE_STRUCT_CAST
2120
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002121
2122template <typename Shape, typename Key>
2123HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124 ASSERT(obj->IsHashTable());
2125 return reinterpret_cast<HashTable*>(obj);
2126}
2127
2128
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002129SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130
ager@chromium.orgac091b72010-05-05 07:34:42 +00002131SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002132
2133
2134uint32_t String::hash_field() {
2135 return READ_UINT32_FIELD(this, kHashFieldOffset);
2136}
2137
2138
2139void String::set_hash_field(uint32_t value) {
2140 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002141#if V8_HOST_ARCH_64_BIT
2142 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2143#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002144}
2145
2146
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147bool String::Equals(String* other) {
2148 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002149 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2150 return false;
2151 }
2152 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153}
2154
2155
lrn@chromium.org303ada72010-10-27 09:33:13 +00002156MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002157 if (!StringShape(this).IsCons()) return this;
2158 ConsString* cons = ConsString::cast(this);
2159 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002160 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161}
2162
2163
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002164String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002165 MaybeObject* flat = TryFlatten(pretenure);
2166 Object* successfully_flattened;
2167 if (flat->ToObject(&successfully_flattened)) {
2168 return String::cast(successfully_flattened);
2169 }
2170 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002171}
2172
2173
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002174uint16_t String::Get(int index) {
2175 ASSERT(index >= 0 && index < length());
2176 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002177 case kSeqStringTag | kAsciiStringTag:
2178 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2179 case kSeqStringTag | kTwoByteStringTag:
2180 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2181 case kConsStringTag | kAsciiStringTag:
2182 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002184 case kExternalStringTag | kAsciiStringTag:
2185 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2186 case kExternalStringTag | kTwoByteStringTag:
2187 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188 default:
2189 break;
2190 }
2191
2192 UNREACHABLE();
2193 return 0;
2194}
2195
2196
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002197void String::Set(int index, uint16_t value) {
2198 ASSERT(index >= 0 && index < length());
2199 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200
ager@chromium.org5ec48922009-05-05 07:25:34 +00002201 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002202 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2203 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002207bool String::IsFlat() {
2208 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002209 case kConsStringTag: {
2210 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002211 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002212 return second->length() == 0;
2213 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002214 default:
2215 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 }
2217}
2218
2219
ager@chromium.org7c537e22008-10-16 08:43:32 +00002220uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221 ASSERT(index >= 0 && index < length());
2222 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2223}
2224
2225
ager@chromium.org7c537e22008-10-16 08:43:32 +00002226void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2228 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2229 static_cast<byte>(value));
2230}
2231
2232
ager@chromium.org7c537e22008-10-16 08:43:32 +00002233Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002234 return FIELD_ADDR(this, kHeaderSize);
2235}
2236
2237
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002238char* SeqAsciiString::GetChars() {
2239 return reinterpret_cast<char*>(GetCharsAddress());
2240}
2241
2242
ager@chromium.org7c537e22008-10-16 08:43:32 +00002243Address SeqTwoByteString::GetCharsAddress() {
2244 return FIELD_ADDR(this, kHeaderSize);
2245}
2246
2247
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002248uc16* SeqTwoByteString::GetChars() {
2249 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2250}
2251
2252
ager@chromium.org7c537e22008-10-16 08:43:32 +00002253uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002254 ASSERT(index >= 0 && index < length());
2255 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2256}
2257
2258
ager@chromium.org7c537e22008-10-16 08:43:32 +00002259void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260 ASSERT(index >= 0 && index < length());
2261 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2262}
2263
2264
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002265int SeqTwoByteString::SeqTwoByteStringSize(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.orgbb29dc92009-03-24 13:25:23 +00002270int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002271 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002272}
2273
2274
ager@chromium.org870a0b62008-11-04 11:43:05 +00002275String* ConsString::first() {
2276 return String::cast(READ_FIELD(this, kFirstOffset));
2277}
2278
2279
2280Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 return READ_FIELD(this, kFirstOffset);
2282}
2283
2284
ager@chromium.org870a0b62008-11-04 11:43:05 +00002285void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002287 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288}
2289
2290
ager@chromium.org870a0b62008-11-04 11:43:05 +00002291String* ConsString::second() {
2292 return String::cast(READ_FIELD(this, kSecondOffset));
2293}
2294
2295
2296Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297 return READ_FIELD(this, kSecondOffset);
2298}
2299
2300
ager@chromium.org870a0b62008-11-04 11:43:05 +00002301void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002303 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002304}
2305
2306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2308 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2309}
2310
2311
2312void ExternalAsciiString::set_resource(
2313 ExternalAsciiString::Resource* resource) {
2314 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2315}
2316
2317
2318ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2319 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2320}
2321
2322
2323void ExternalTwoByteString::set_resource(
2324 ExternalTwoByteString::Resource* resource) {
2325 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2326}
2327
2328
ager@chromium.orgac091b72010-05-05 07:34:42 +00002329void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002330 set_finger_index(kEntriesIndex);
2331 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002332}
2333
2334
2335void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002336 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002337 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002338 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002339 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002340 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002341 MakeZeroSize();
2342}
2343
2344
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002345int JSFunctionResultCache::size() {
2346 return Smi::cast(get(kCacheSizeIndex))->value();
2347}
2348
2349
2350void JSFunctionResultCache::set_size(int size) {
2351 set(kCacheSizeIndex, Smi::FromInt(size));
2352}
2353
2354
2355int JSFunctionResultCache::finger_index() {
2356 return Smi::cast(get(kFingerIndex))->value();
2357}
2358
2359
2360void JSFunctionResultCache::set_finger_index(int finger_index) {
2361 set(kFingerIndex, Smi::FromInt(finger_index));
2362}
2363
2364
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365byte ByteArray::get(int index) {
2366 ASSERT(index >= 0 && index < this->length());
2367 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2368}
2369
2370
2371void ByteArray::set(int index, byte value) {
2372 ASSERT(index >= 0 && index < this->length());
2373 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2374}
2375
2376
2377int ByteArray::get_int(int index) {
2378 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2379 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2380}
2381
2382
2383ByteArray* ByteArray::FromDataStartAddress(Address address) {
2384 ASSERT_TAG_ALIGNED(address);
2385 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2386}
2387
2388
2389Address ByteArray::GetDataStartAddress() {
2390 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2391}
2392
2393
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002394uint8_t* ExternalPixelArray::external_pixel_pointer() {
2395 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002396}
2397
2398
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002399uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002400 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002401 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002402 return ptr[index];
2403}
2404
2405
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002406MaybeObject* ExternalPixelArray::get(int index) {
2407 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2408}
2409
2410
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002411void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002412 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002413 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002414 ptr[index] = value;
2415}
2416
2417
ager@chromium.org3811b432009-10-28 14:53:37 +00002418void* ExternalArray::external_pointer() {
2419 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2420 return reinterpret_cast<void*>(ptr);
2421}
2422
2423
2424void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2425 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2426 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2427}
2428
2429
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002430int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002431 ASSERT((index >= 0) && (index < this->length()));
2432 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2433 return ptr[index];
2434}
2435
2436
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002437MaybeObject* ExternalByteArray::get(int index) {
2438 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2439}
2440
2441
ager@chromium.org3811b432009-10-28 14:53:37 +00002442void ExternalByteArray::set(int index, int8_t value) {
2443 ASSERT((index >= 0) && (index < this->length()));
2444 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2445 ptr[index] = value;
2446}
2447
2448
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002449uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002450 ASSERT((index >= 0) && (index < this->length()));
2451 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2452 return ptr[index];
2453}
2454
2455
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002456MaybeObject* ExternalUnsignedByteArray::get(int index) {
2457 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2458}
2459
2460
ager@chromium.org3811b432009-10-28 14:53:37 +00002461void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2462 ASSERT((index >= 0) && (index < this->length()));
2463 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2464 ptr[index] = value;
2465}
2466
2467
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002468int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002469 ASSERT((index >= 0) && (index < this->length()));
2470 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2471 return ptr[index];
2472}
2473
2474
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002475MaybeObject* ExternalShortArray::get(int index) {
2476 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2477}
2478
2479
ager@chromium.org3811b432009-10-28 14:53:37 +00002480void ExternalShortArray::set(int index, int16_t value) {
2481 ASSERT((index >= 0) && (index < this->length()));
2482 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2483 ptr[index] = value;
2484}
2485
2486
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002487uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002488 ASSERT((index >= 0) && (index < this->length()));
2489 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2490 return ptr[index];
2491}
2492
2493
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002494MaybeObject* ExternalUnsignedShortArray::get(int index) {
2495 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2496}
2497
2498
ager@chromium.org3811b432009-10-28 14:53:37 +00002499void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2500 ASSERT((index >= 0) && (index < this->length()));
2501 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2502 ptr[index] = value;
2503}
2504
2505
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002506int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002507 ASSERT((index >= 0) && (index < this->length()));
2508 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2509 return ptr[index];
2510}
2511
2512
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002513MaybeObject* ExternalIntArray::get(int index) {
2514 return GetHeap()->NumberFromInt32(get_scalar(index));
2515}
2516
2517
ager@chromium.org3811b432009-10-28 14:53:37 +00002518void ExternalIntArray::set(int index, int32_t value) {
2519 ASSERT((index >= 0) && (index < this->length()));
2520 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2521 ptr[index] = value;
2522}
2523
2524
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002525uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002526 ASSERT((index >= 0) && (index < this->length()));
2527 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2528 return ptr[index];
2529}
2530
2531
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002532MaybeObject* ExternalUnsignedIntArray::get(int index) {
2533 return GetHeap()->NumberFromUint32(get_scalar(index));
2534}
2535
2536
ager@chromium.org3811b432009-10-28 14:53:37 +00002537void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2538 ASSERT((index >= 0) && (index < this->length()));
2539 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2540 ptr[index] = value;
2541}
2542
2543
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002544float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002545 ASSERT((index >= 0) && (index < this->length()));
2546 float* ptr = static_cast<float*>(external_pointer());
2547 return ptr[index];
2548}
2549
2550
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002551MaybeObject* ExternalFloatArray::get(int index) {
2552 return GetHeap()->NumberFromDouble(get_scalar(index));
2553}
2554
2555
ager@chromium.org3811b432009-10-28 14:53:37 +00002556void ExternalFloatArray::set(int index, float value) {
2557 ASSERT((index >= 0) && (index < this->length()));
2558 float* ptr = static_cast<float*>(external_pointer());
2559 ptr[index] = value;
2560}
2561
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002562
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002563double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002564 ASSERT((index >= 0) && (index < this->length()));
2565 double* ptr = static_cast<double*>(external_pointer());
2566 return ptr[index];
2567}
2568
2569
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002570MaybeObject* ExternalDoubleArray::get(int index) {
2571 return GetHeap()->NumberFromDouble(get_scalar(index));
2572}
2573
2574
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002575void ExternalDoubleArray::set(int index, double value) {
2576 ASSERT((index >= 0) && (index < this->length()));
2577 double* ptr = static_cast<double*>(external_pointer());
2578 ptr[index] = value;
2579}
2580
2581
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002582int Map::visitor_id() {
2583 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2584}
2585
2586
2587void Map::set_visitor_id(int id) {
2588 ASSERT(0 <= id && id < 256);
2589 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2590}
2591
ager@chromium.org3811b432009-10-28 14:53:37 +00002592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002593int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002594 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2595}
2596
2597
2598int Map::inobject_properties() {
2599 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600}
2601
2602
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002603int Map::pre_allocated_property_fields() {
2604 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2605}
2606
2607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002609 int instance_size = map->instance_size();
2610 if (instance_size != kVariableSizeSentinel) return instance_size;
2611 // We can ignore the "symbol" bit becase it is only set for symbols
2612 // and implies a string type.
2613 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002614 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002615 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002616 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002617 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002618 if (instance_type == ASCII_STRING_TYPE) {
2619 return SeqAsciiString::SizeFor(
2620 reinterpret_cast<SeqAsciiString*>(this)->length());
2621 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002622 if (instance_type == BYTE_ARRAY_TYPE) {
2623 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2624 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002625 if (instance_type == STRING_TYPE) {
2626 return SeqTwoByteString::SizeFor(
2627 reinterpret_cast<SeqTwoByteString*>(this)->length());
2628 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002629 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2630 return FixedDoubleArray::SizeFor(
2631 reinterpret_cast<FixedDoubleArray*>(this)->length());
2632 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002633 ASSERT(instance_type == CODE_TYPE);
2634 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002635}
2636
2637
2638void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002639 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002640 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641 ASSERT(0 <= value && value < 256);
2642 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2643}
2644
2645
ager@chromium.org7c537e22008-10-16 08:43:32 +00002646void Map::set_inobject_properties(int value) {
2647 ASSERT(0 <= value && value < 256);
2648 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2649}
2650
2651
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002652void Map::set_pre_allocated_property_fields(int value) {
2653 ASSERT(0 <= value && value < 256);
2654 WRITE_BYTE_FIELD(this,
2655 kPreAllocatedPropertyFieldsOffset,
2656 static_cast<byte>(value));
2657}
2658
2659
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002660InstanceType Map::instance_type() {
2661 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2662}
2663
2664
2665void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002666 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2667}
2668
2669
2670int Map::unused_property_fields() {
2671 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2672}
2673
2674
2675void Map::set_unused_property_fields(int value) {
2676 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2677}
2678
2679
2680byte Map::bit_field() {
2681 return READ_BYTE_FIELD(this, kBitFieldOffset);
2682}
2683
2684
2685void Map::set_bit_field(byte value) {
2686 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2687}
2688
2689
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002690byte Map::bit_field2() {
2691 return READ_BYTE_FIELD(this, kBitField2Offset);
2692}
2693
2694
2695void Map::set_bit_field2(byte value) {
2696 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2697}
2698
2699
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700void Map::set_non_instance_prototype(bool value) {
2701 if (value) {
2702 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2703 } else {
2704 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2705 }
2706}
2707
2708
2709bool Map::has_non_instance_prototype() {
2710 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2711}
2712
2713
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002714void Map::set_function_with_prototype(bool value) {
2715 if (value) {
2716 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2717 } else {
2718 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2719 }
2720}
2721
2722
2723bool Map::function_with_prototype() {
2724 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2725}
2726
2727
ager@chromium.org870a0b62008-11-04 11:43:05 +00002728void Map::set_is_access_check_needed(bool access_check_needed) {
2729 if (access_check_needed) {
2730 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2731 } else {
2732 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2733 }
2734}
2735
2736
2737bool Map::is_access_check_needed() {
2738 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2739}
2740
2741
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002742void Map::set_is_extensible(bool value) {
2743 if (value) {
2744 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2745 } else {
2746 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2747 }
2748}
2749
2750bool Map::is_extensible() {
2751 return ((1 << kIsExtensible) & bit_field2()) != 0;
2752}
2753
2754
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002755void Map::set_attached_to_shared_function_info(bool value) {
2756 if (value) {
2757 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2758 } else {
2759 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2760 }
2761}
2762
2763bool Map::attached_to_shared_function_info() {
2764 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2765}
2766
2767
2768void Map::set_is_shared(bool value) {
2769 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002770 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002771 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002772 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002773 }
2774}
2775
2776bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002777 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002778}
2779
2780
2781JSFunction* Map::unchecked_constructor() {
2782 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2783}
2784
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002785
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002786FixedArray* Map::unchecked_prototype_transitions() {
2787 return reinterpret_cast<FixedArray*>(
2788 READ_FIELD(this, kPrototypeTransitionsOffset));
2789}
2790
2791
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002792Code::Flags Code::flags() {
2793 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2794}
2795
2796
2797void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002798 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002799 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002800 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2801 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802 ExtractArgumentsCountFromFlags(flags) >= 0);
2803 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2804}
2805
2806
2807Code::Kind Code::kind() {
2808 return ExtractKindFromFlags(flags());
2809}
2810
2811
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002812InLoopFlag Code::ic_in_loop() {
2813 return ExtractICInLoopFromFlags(flags());
2814}
2815
2816
kasper.lund7276f142008-07-30 08:49:36 +00002817InlineCacheState Code::ic_state() {
2818 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002819 // Only allow uninitialized or debugger states for non-IC code
2820 // objects. This is used in the debugger to determine whether or not
2821 // a call to code object has been replaced with a debug break call.
2822 ASSERT(is_inline_cache_stub() ||
2823 result == UNINITIALIZED ||
2824 result == DEBUG_BREAK ||
2825 result == DEBUG_PREPARE_STEP_IN);
2826 return result;
2827}
2828
2829
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002830Code::ExtraICState Code::extra_ic_state() {
2831 ASSERT(is_inline_cache_stub());
2832 return ExtractExtraICStateFromFlags(flags());
2833}
2834
2835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002837 return ExtractTypeFromFlags(flags());
2838}
2839
2840
2841int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002842 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843 return ExtractArgumentsCountFromFlags(flags());
2844}
2845
2846
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002847int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002848 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002849 kind() == UNARY_OP_IC ||
2850 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002851 kind() == COMPARE_IC ||
2852 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002853 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002854}
2855
2856
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002857void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002859 kind() == UNARY_OP_IC ||
2860 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002861 kind() == COMPARE_IC ||
2862 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002863 ASSERT(0 <= major && major < 256);
2864 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865}
2866
2867
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002868bool Code::optimizable() {
2869 ASSERT(kind() == FUNCTION);
2870 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2871}
2872
2873
2874void Code::set_optimizable(bool value) {
2875 ASSERT(kind() == FUNCTION);
2876 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2877}
2878
2879
2880bool Code::has_deoptimization_support() {
2881 ASSERT(kind() == FUNCTION);
2882 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2883}
2884
2885
2886void Code::set_has_deoptimization_support(bool value) {
2887 ASSERT(kind() == FUNCTION);
2888 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2889}
2890
2891
2892int Code::allow_osr_at_loop_nesting_level() {
2893 ASSERT(kind() == FUNCTION);
2894 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2895}
2896
2897
2898void Code::set_allow_osr_at_loop_nesting_level(int level) {
2899 ASSERT(kind() == FUNCTION);
2900 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2901 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2902}
2903
2904
2905unsigned Code::stack_slots() {
2906 ASSERT(kind() == OPTIMIZED_FUNCTION);
2907 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2908}
2909
2910
2911void Code::set_stack_slots(unsigned slots) {
2912 ASSERT(kind() == OPTIMIZED_FUNCTION);
2913 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2914}
2915
2916
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002917unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002919 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920}
2921
2922
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002923void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 ASSERT(kind() == OPTIMIZED_FUNCTION);
2925 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002926 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927}
2928
2929
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002930unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002932 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933}
2934
2935
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002936void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002937 ASSERT(kind() == FUNCTION);
2938 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002939 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940}
2941
2942
2943CheckType Code::check_type() {
2944 ASSERT(is_call_stub() || is_keyed_call_stub());
2945 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2946 return static_cast<CheckType>(type);
2947}
2948
2949
2950void Code::set_check_type(CheckType value) {
2951 ASSERT(is_call_stub() || is_keyed_call_stub());
2952 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2953}
2954
2955
danno@chromium.org40cb8782011-05-25 07:58:50 +00002956byte Code::unary_op_type() {
2957 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002958 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2959}
2960
2961
danno@chromium.org40cb8782011-05-25 07:58:50 +00002962void Code::set_unary_op_type(byte value) {
2963 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002964 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2965}
2966
2967
danno@chromium.org40cb8782011-05-25 07:58:50 +00002968byte Code::binary_op_type() {
2969 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2971}
2972
2973
danno@chromium.org40cb8782011-05-25 07:58:50 +00002974void Code::set_binary_op_type(byte value) {
2975 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002976 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2977}
2978
2979
danno@chromium.org40cb8782011-05-25 07:58:50 +00002980byte Code::binary_op_result_type() {
2981 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2983}
2984
2985
danno@chromium.org40cb8782011-05-25 07:58:50 +00002986void Code::set_binary_op_result_type(byte value) {
2987 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002988 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2989}
2990
2991
2992byte Code::compare_state() {
2993 ASSERT(is_compare_ic_stub());
2994 return READ_BYTE_FIELD(this, kCompareStateOffset);
2995}
2996
2997
2998void Code::set_compare_state(byte value) {
2999 ASSERT(is_compare_ic_stub());
3000 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3001}
3002
3003
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003004byte Code::to_boolean_state() {
3005 ASSERT(is_to_boolean_ic_stub());
3006 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3007}
3008
3009
3010void Code::set_to_boolean_state(byte value) {
3011 ASSERT(is_to_boolean_ic_stub());
3012 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3013}
3014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003015bool Code::is_inline_cache_stub() {
3016 Kind kind = this->kind();
3017 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3018}
3019
3020
3021Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003022 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00003023 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003024 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003026 int argc,
3027 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003028 // Extra IC state is only allowed for call IC stubs or for store IC
3029 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003030 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003031 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003032 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003033 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034 // Compute the bit mask.
3035 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003036 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00003037 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003038 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003039 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003040 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003041 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003042 // Cast to flags and validate result before returning it.
3043 Flags result = static_cast<Flags>(bits);
3044 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00003045 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003046 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003047 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003048 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
3050 return result;
3051}
3052
3053
3054Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3055 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003056 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003057 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003058 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003060 return ComputeFlags(
3061 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003062}
3063
3064
3065Code::Kind Code::ExtractKindFromFlags(Flags flags) {
3066 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
3067 return static_cast<Kind>(bits);
3068}
3069
3070
kasper.lund7276f142008-07-30 08:49:36 +00003071InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
3072 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003073 return static_cast<InlineCacheState>(bits);
3074}
3075
3076
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003077Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3078 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
3079 return static_cast<ExtraICState>(bits);
3080}
3081
3082
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003083InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
3084 int bits = (flags & kFlagsICInLoopMask);
3085 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3086}
3087
3088
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003089PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3090 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3091 return static_cast<PropertyType>(bits);
3092}
3093
3094
3095int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3096 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3097}
3098
3099
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003100InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3101 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3102 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3103}
3104
3105
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3107 int bits = flags & ~kFlagsTypeMask;
3108 return static_cast<Flags>(bits);
3109}
3110
3111
ager@chromium.org8bb60582008-12-11 12:02:20 +00003112Code* Code::GetCodeFromTargetAddress(Address address) {
3113 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3114 // GetCodeFromTargetAddress might be called when marking objects during mark
3115 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3116 // Code::cast. Code::cast does not work when the object's map is
3117 // marked.
3118 Code* result = reinterpret_cast<Code*>(code);
3119 return result;
3120}
3121
3122
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003123Isolate* Map::isolate() {
3124 return heap()->isolate();
3125}
3126
3127
3128Heap* Map::heap() {
3129 // NOTE: address() helper is not used to save one instruction.
3130 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3131 ASSERT(heap != NULL);
3132 ASSERT(heap->isolate() == Isolate::Current());
3133 return heap;
3134}
3135
3136
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003137Heap* Code::heap() {
3138 // NOTE: address() helper is not used to save one instruction.
3139 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3140 ASSERT(heap != NULL);
3141 ASSERT(heap->isolate() == Isolate::Current());
3142 return heap;
3143}
3144
3145
3146Isolate* Code::isolate() {
3147 return heap()->isolate();
3148}
3149
3150
3151Heap* JSGlobalPropertyCell::heap() {
3152 // NOTE: address() helper is not used to save one instruction.
3153 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3154 ASSERT(heap != NULL);
3155 ASSERT(heap->isolate() == Isolate::Current());
3156 return heap;
3157}
3158
3159
3160Isolate* JSGlobalPropertyCell::isolate() {
3161 return heap()->isolate();
3162}
3163
3164
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003165Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3166 return HeapObject::
3167 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3168}
3169
3170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003171Object* Map::prototype() {
3172 return READ_FIELD(this, kPrototypeOffset);
3173}
3174
3175
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003176void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003177 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003178 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003179 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003180}
3181
3182
lrn@chromium.org303ada72010-10-27 09:33:13 +00003183MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003184 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003185 Object* obj;
3186 { MaybeObject* maybe_obj = CopyDropTransitions();
3187 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3188 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003189 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003190 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003191 isolate()->counters()->map_to_fast_elements()->Increment();
3192 return new_map;
3193}
3194
3195
3196MaybeObject* Map::GetFastDoubleElementsMap() {
3197 if (has_fast_double_elements()) return this;
3198 Object* obj;
3199 { MaybeObject* maybe_obj = CopyDropTransitions();
3200 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3201 }
3202 Map* new_map = Map::cast(obj);
3203 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3204 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003205 return new_map;
3206}
3207
3208
lrn@chromium.org303ada72010-10-27 09:33:13 +00003209MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003210 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003211 Object* obj;
3212 { MaybeObject* maybe_obj = CopyDropTransitions();
3213 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3214 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003215 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003216 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003217 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003218 return new_map;
3219}
3220
3221
danno@chromium.org40cb8782011-05-25 07:58:50 +00003222DescriptorArray* Map::instance_descriptors() {
3223 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3224 if (object->IsSmi()) {
3225 return HEAP->empty_descriptor_array();
3226 } else {
3227 return DescriptorArray::cast(object);
3228 }
3229}
3230
3231
3232void Map::init_instance_descriptors() {
3233 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3234}
3235
3236
3237void Map::clear_instance_descriptors() {
3238 Object* object = READ_FIELD(this,
3239 kInstanceDescriptorsOrBitField3Offset);
3240 if (!object->IsSmi()) {
3241 WRITE_FIELD(
3242 this,
3243 kInstanceDescriptorsOrBitField3Offset,
3244 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3245 }
3246}
3247
3248
3249void Map::set_instance_descriptors(DescriptorArray* value,
3250 WriteBarrierMode mode) {
3251 Object* object = READ_FIELD(this,
3252 kInstanceDescriptorsOrBitField3Offset);
3253 if (value == isolate()->heap()->empty_descriptor_array()) {
3254 clear_instance_descriptors();
3255 return;
3256 } else {
3257 if (object->IsSmi()) {
3258 value->set_bit_field3_storage(Smi::cast(object)->value());
3259 } else {
3260 value->set_bit_field3_storage(
3261 DescriptorArray::cast(object)->bit_field3_storage());
3262 }
3263 }
3264 ASSERT(!is_shared());
3265 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3266 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3267 this,
3268 kInstanceDescriptorsOrBitField3Offset,
3269 mode);
3270}
3271
3272
3273int Map::bit_field3() {
3274 Object* object = READ_FIELD(this,
3275 kInstanceDescriptorsOrBitField3Offset);
3276 if (object->IsSmi()) {
3277 return Smi::cast(object)->value();
3278 } else {
3279 return DescriptorArray::cast(object)->bit_field3_storage();
3280 }
3281}
3282
3283
3284void Map::set_bit_field3(int value) {
3285 ASSERT(Smi::IsValid(value));
3286 Object* object = READ_FIELD(this,
3287 kInstanceDescriptorsOrBitField3Offset);
3288 if (object->IsSmi()) {
3289 WRITE_FIELD(this,
3290 kInstanceDescriptorsOrBitField3Offset,
3291 Smi::FromInt(value));
3292 } else {
3293 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3294 }
3295}
3296
3297
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003298ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003299ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300ACCESSORS(Map, constructor, Object, kConstructorOffset)
3301
3302ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3303ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003304ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3305 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003306
3307ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3308ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003309ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003310
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003311ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312
3313ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3314ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3315ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3316ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3317ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3318
3319ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3320ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3321ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3322
3323ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3324ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3325ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3326ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3327ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3328ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3329
3330ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3331ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3332
3333ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3334ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3335
3336ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3337ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3339 kPropertyAccessorsOffset)
3340ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3341 kPrototypeTemplateOffset)
3342ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3343ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3344 kNamedPropertyHandlerOffset)
3345ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3346 kIndexedPropertyHandlerOffset)
3347ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3348 kInstanceTemplateOffset)
3349ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3350ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3352 kInstanceCallHandlerOffset)
3353ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3354 kAccessCheckInfoOffset)
3355ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3356
3357ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003358ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3359 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360
3361ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3362ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3363
3364ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3365
3366ACCESSORS(Script, source, Object, kSourceOffset)
3367ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003368ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3370ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003371ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003372ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003373ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003374ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003375ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003376ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003377ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003378ACCESSORS(Script, eval_from_instructions_offset, Smi,
3379 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003381#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3383ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3384ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3385ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3386
3387ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3388ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3389ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3390ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003391#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392
3393ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003394ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3395ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3397 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003398ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003399ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3400ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003401ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003402ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3403 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003404
3405BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3406 kHiddenPrototypeBit)
3407BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3408BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3409 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003410BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3411 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3413 kIsExpressionBit)
3414BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3415 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003416BOOL_GETTER(SharedFunctionInfo,
3417 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003418 has_only_simple_this_property_assignments,
3419 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003420BOOL_ACCESSORS(SharedFunctionInfo,
3421 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003422 allows_lazy_compilation,
3423 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003424BOOL_ACCESSORS(SharedFunctionInfo,
3425 compiler_hints,
3426 uses_arguments,
3427 kUsesArguments)
3428BOOL_ACCESSORS(SharedFunctionInfo,
3429 compiler_hints,
3430 has_duplicate_parameters,
3431 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003432
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003433
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003434#if V8_HOST_ARCH_32_BIT
3435SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3436SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003437 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003438SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003439 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003440SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3441SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003443SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3444SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003445 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003446SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003447 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003448SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003449 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003451#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003453#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003454 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003455 int holder::name() { \
3456 int value = READ_INT_FIELD(this, offset); \
3457 ASSERT(kHeapObjectTag == 1); \
3458 ASSERT((value & kHeapObjectTag) == 0); \
3459 return value >> 1; \
3460 } \
3461 void holder::set_##name(int value) { \
3462 ASSERT(kHeapObjectTag == 1); \
3463 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3464 (value & 0xC0000000) == 0x000000000); \
3465 WRITE_INT_FIELD(this, \
3466 offset, \
3467 (value << 1) & ~kHeapObjectTag); \
3468 }
3469
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003470#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3471 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003472 INT_ACCESSORS(holder, name, offset)
3473
3474
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003475PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003476PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3477 formal_parameter_count,
3478 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003479
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003480PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3481 expected_nof_properties,
3482 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003483PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3484
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003485PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3486PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3487 start_position_and_type,
3488 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003489
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003490PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3491 function_token_position,
3492 kFunctionTokenPositionOffset)
3493PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3494 compiler_hints,
3495 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003496
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003497PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3498 this_property_assignments_count,
3499 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003500PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003501#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003503
3504int SharedFunctionInfo::construction_count() {
3505 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3506}
3507
3508
3509void SharedFunctionInfo::set_construction_count(int value) {
3510 ASSERT(0 <= value && value < 256);
3511 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3512}
3513
3514
whesse@chromium.org7b260152011-06-20 15:33:18 +00003515BOOL_ACCESSORS(SharedFunctionInfo,
3516 compiler_hints,
3517 live_objects_may_exist,
3518 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003519
3520
3521bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003522 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003523}
3524
3525
whesse@chromium.org7b260152011-06-20 15:33:18 +00003526BOOL_GETTER(SharedFunctionInfo,
3527 compiler_hints,
3528 optimization_disabled,
3529 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003530
3531
3532void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3533 set_compiler_hints(BooleanBit::set(compiler_hints(),
3534 kOptimizationDisabled,
3535 disable));
3536 // If disabling optimizations we reflect that in the code object so
3537 // it will not be counted as optimizable code.
3538 if ((code()->kind() == Code::FUNCTION) && disable) {
3539 code()->set_optimizable(false);
3540 }
3541}
3542
3543
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003544BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003545 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003546BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3547BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3548 name_should_print_as_anonymous,
3549 kNameShouldPrintAsAnonymous)
3550BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3551BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003552
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003553ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3554ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3555
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003556ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3557
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003558bool Script::HasValidSource() {
3559 Object* src = this->source();
3560 if (!src->IsString()) return true;
3561 String* src_str = String::cast(src);
3562 if (!StringShape(src_str).IsExternal()) return true;
3563 if (src_str->IsAsciiRepresentation()) {
3564 return ExternalAsciiString::cast(src)->resource() != NULL;
3565 } else if (src_str->IsTwoByteRepresentation()) {
3566 return ExternalTwoByteString::cast(src)->resource() != NULL;
3567 }
3568 return true;
3569}
3570
3571
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003572void SharedFunctionInfo::DontAdaptArguments() {
3573 ASSERT(code()->kind() == Code::BUILTIN);
3574 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3575}
3576
3577
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578int SharedFunctionInfo::start_position() {
3579 return start_position_and_type() >> kStartPositionShift;
3580}
3581
3582
3583void SharedFunctionInfo::set_start_position(int start_position) {
3584 set_start_position_and_type((start_position << kStartPositionShift)
3585 | (start_position_and_type() & ~kStartPositionMask));
3586}
3587
3588
3589Code* SharedFunctionInfo::code() {
3590 return Code::cast(READ_FIELD(this, kCodeOffset));
3591}
3592
3593
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003594Code* SharedFunctionInfo::unchecked_code() {
3595 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3596}
3597
3598
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003599void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003600 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003601 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003602}
3603
3604
ager@chromium.orgb5737492010-07-15 09:29:43 +00003605SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3606 return reinterpret_cast<SerializedScopeInfo*>(
3607 READ_FIELD(this, kScopeInfoOffset));
3608}
3609
3610
3611void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3612 WriteBarrierMode mode) {
3613 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003614 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003615}
3616
3617
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618Smi* SharedFunctionInfo::deopt_counter() {
3619 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3620}
3621
3622
3623void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3624 WRITE_FIELD(this, kDeoptCounterOffset, value);
3625}
3626
3627
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003628bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003629 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003630 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003631}
3632
3633
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003634bool SharedFunctionInfo::IsApiFunction() {
3635 return function_data()->IsFunctionTemplateInfo();
3636}
3637
3638
3639FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3640 ASSERT(IsApiFunction());
3641 return FunctionTemplateInfo::cast(function_data());
3642}
3643
3644
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003645bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003646 return function_data()->IsSmi();
3647}
3648
3649
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003650BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3651 ASSERT(HasBuiltinFunctionId());
3652 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003653}
3654
3655
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003656int SharedFunctionInfo::code_age() {
3657 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3658}
3659
3660
3661void SharedFunctionInfo::set_code_age(int code_age) {
3662 set_compiler_hints(compiler_hints() |
3663 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3664}
3665
3666
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003667bool SharedFunctionInfo::has_deoptimization_support() {
3668 Code* code = this->code();
3669 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3670}
3671
3672
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003673bool JSFunction::IsBuiltin() {
3674 return context()->global()->IsJSBuiltinsObject();
3675}
3676
3677
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003678bool JSFunction::NeedsArgumentsAdaption() {
3679 return shared()->formal_parameter_count() !=
3680 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3681}
3682
3683
3684bool JSFunction::IsOptimized() {
3685 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3686}
3687
3688
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003689bool JSFunction::IsOptimizable() {
3690 return code()->kind() == Code::FUNCTION && code()->optimizable();
3691}
3692
3693
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003694bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003695 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003696}
3697
3698
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003699Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003700 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701}
3702
3703
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003704Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003705 return reinterpret_cast<Code*>(
3706 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003707}
3708
3709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003710void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003711 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003712 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003713 Address entry = value->entry();
3714 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003715}
3716
3717
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003718void JSFunction::ReplaceCode(Code* code) {
3719 bool was_optimized = IsOptimized();
3720 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3721
3722 set_code(code);
3723
3724 // Add/remove the function from the list of optimized functions for this
3725 // context based on the state change.
3726 if (!was_optimized && is_optimized) {
3727 context()->global_context()->AddOptimizedFunction(this);
3728 }
3729 if (was_optimized && !is_optimized) {
3730 context()->global_context()->RemoveOptimizedFunction(this);
3731 }
3732}
3733
3734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003735Context* JSFunction::context() {
3736 return Context::cast(READ_FIELD(this, kContextOffset));
3737}
3738
3739
3740Object* JSFunction::unchecked_context() {
3741 return READ_FIELD(this, kContextOffset);
3742}
3743
3744
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003745SharedFunctionInfo* JSFunction::unchecked_shared() {
3746 return reinterpret_cast<SharedFunctionInfo*>(
3747 READ_FIELD(this, kSharedFunctionInfoOffset));
3748}
3749
3750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003751void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003752 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003753 WRITE_FIELD(this, kContextOffset, value);
3754 WRITE_BARRIER(this, kContextOffset);
3755}
3756
3757ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3758 kPrototypeOrInitialMapOffset)
3759
3760
3761Map* JSFunction::initial_map() {
3762 return Map::cast(prototype_or_initial_map());
3763}
3764
3765
3766void JSFunction::set_initial_map(Map* value) {
3767 set_prototype_or_initial_map(value);
3768}
3769
3770
3771bool JSFunction::has_initial_map() {
3772 return prototype_or_initial_map()->IsMap();
3773}
3774
3775
3776bool JSFunction::has_instance_prototype() {
3777 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3778}
3779
3780
3781bool JSFunction::has_prototype() {
3782 return map()->has_non_instance_prototype() || has_instance_prototype();
3783}
3784
3785
3786Object* JSFunction::instance_prototype() {
3787 ASSERT(has_instance_prototype());
3788 if (has_initial_map()) return initial_map()->prototype();
3789 // When there is no initial map and the prototype is a JSObject, the
3790 // initial map field is used for the prototype field.
3791 return prototype_or_initial_map();
3792}
3793
3794
3795Object* JSFunction::prototype() {
3796 ASSERT(has_prototype());
3797 // If the function's prototype property has been set to a non-JSObject
3798 // value, that value is stored in the constructor field of the map.
3799 if (map()->has_non_instance_prototype()) return map()->constructor();
3800 return instance_prototype();
3801}
3802
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003803bool JSFunction::should_have_prototype() {
3804 return map()->function_with_prototype();
3805}
3806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807
3808bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003809 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003810}
3811
3812
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003813int JSFunction::NumberOfLiterals() {
3814 return literals()->length();
3815}
3816
3817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003818Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003819 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003820 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003821}
3822
3823
3824void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3825 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003826 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003827 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3828 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3829}
3830
3831
3832Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003833 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003834 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3835}
3836
3837
3838void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3839 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003840 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003841 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003842 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003843}
3844
3845
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003846ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003847ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003848
3849
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003850ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3851ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3852
3853
3854ObjectHashTable* JSWeakMap::unchecked_table() {
3855 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3856}
3857
3858
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003859Address Foreign::address() {
3860 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861}
3862
3863
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003864void Foreign::set_address(Address value) {
3865 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003866}
3867
3868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003869ACCESSORS(JSValue, value, Object, kValueOffset)
3870
3871
3872JSValue* JSValue::cast(Object* obj) {
3873 ASSERT(obj->IsJSValue());
3874 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3875 return reinterpret_cast<JSValue*>(obj);
3876}
3877
3878
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003879ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3880ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3881ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3882ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3883ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3884SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3885SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3886
3887
3888JSMessageObject* JSMessageObject::cast(Object* obj) {
3889 ASSERT(obj->IsJSMessageObject());
3890 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3891 return reinterpret_cast<JSMessageObject*>(obj);
3892}
3893
3894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003896ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003898ACCESSORS(Code, next_code_flushing_candidate,
3899 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003900
3901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003902byte* Code::instruction_start() {
3903 return FIELD_ADDR(this, kHeaderSize);
3904}
3905
3906
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003907byte* Code::instruction_end() {
3908 return instruction_start() + instruction_size();
3909}
3910
3911
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003912int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003913 return RoundUp(instruction_size(), kObjectAlignment);
3914}
3915
3916
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003917FixedArray* Code::unchecked_deoptimization_data() {
3918 return reinterpret_cast<FixedArray*>(
3919 READ_FIELD(this, kDeoptimizationDataOffset));
3920}
3921
3922
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003923ByteArray* Code::unchecked_relocation_info() {
3924 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925}
3926
3927
3928byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003929 return unchecked_relocation_info()->GetDataStartAddress();
3930}
3931
3932
3933int Code::relocation_size() {
3934 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935}
3936
3937
3938byte* Code::entry() {
3939 return instruction_start();
3940}
3941
3942
3943bool Code::contains(byte* pc) {
3944 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003945 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003946}
3947
3948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003949ACCESSORS(JSArray, length, Object, kLengthOffset)
3950
3951
ager@chromium.org236ad962008-09-25 09:45:57 +00003952ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003953
3954
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003955JSRegExp::Type JSRegExp::TypeTag() {
3956 Object* data = this->data();
3957 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3958 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3959 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003960}
3961
3962
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003963JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3964 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3965 return static_cast<JSRegExp::Type>(smi->value());
3966}
3967
3968
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003969int JSRegExp::CaptureCount() {
3970 switch (TypeTag()) {
3971 case ATOM:
3972 return 0;
3973 case IRREGEXP:
3974 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3975 default:
3976 UNREACHABLE();
3977 return -1;
3978 }
3979}
3980
3981
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003982JSRegExp::Flags JSRegExp::GetFlags() {
3983 ASSERT(this->data()->IsFixedArray());
3984 Object* data = this->data();
3985 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3986 return Flags(smi->value());
3987}
3988
3989
3990String* JSRegExp::Pattern() {
3991 ASSERT(this->data()->IsFixedArray());
3992 Object* data = this->data();
3993 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3994 return pattern;
3995}
3996
3997
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003998Object* JSRegExp::DataAt(int index) {
3999 ASSERT(TypeTag() != NOT_COMPILED);
4000 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004001}
4002
4003
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004004Object* JSRegExp::DataAtUnchecked(int index) {
4005 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4006 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4007 return READ_FIELD(fa, offset);
4008}
4009
4010
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004011void JSRegExp::SetDataAt(int index, Object* value) {
4012 ASSERT(TypeTag() != NOT_COMPILED);
4013 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4014 FixedArray::cast(data())->set(index, value);
4015}
4016
4017
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004018void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4019 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4020 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4021 if (value->IsSmi()) {
4022 fa->set_unchecked(index, Smi::cast(value));
4023 } else {
4024 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4025 }
4026}
4027
4028
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004029JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004030 ElementsKind kind = map()->elements_kind();
4031 ASSERT((kind == FAST_ELEMENTS &&
4032 (elements()->map() == GetHeap()->fixed_array_map() ||
4033 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004034 (kind == FAST_DOUBLE_ELEMENTS &&
4035 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004036 (kind == DICTIONARY_ELEMENTS &&
4037 elements()->IsFixedArray() &&
4038 elements()->IsDictionary()) ||
4039 (kind > DICTIONARY_ELEMENTS));
4040 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004041}
4042
4043
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004044ElementsAccessor* JSObject::GetElementsAccessor() {
4045 return ElementsAccessor::ForKind(GetElementsKind());
4046}
4047
4048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004049bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004050 return GetElementsKind() == FAST_ELEMENTS;
4051}
4052
4053
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004054bool JSObject::HasFastDoubleElements() {
4055 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4056}
4057
4058
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004059bool JSObject::HasDictionaryElements() {
4060 return GetElementsKind() == DICTIONARY_ELEMENTS;
4061}
4062
4063
ager@chromium.org3811b432009-10-28 14:53:37 +00004064bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004065 HeapObject* array = elements();
4066 ASSERT(array != NULL);
4067 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004068}
4069
4070
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004071#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4072bool JSObject::HasExternal##name##Elements() { \
4073 HeapObject* array = elements(); \
4074 ASSERT(array != NULL); \
4075 if (!array->IsHeapObject()) \
4076 return false; \
4077 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004078}
4079
4080
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004081EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4082EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4083EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4084EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4085 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4086EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4087EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4088 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4089EXTERNAL_ELEMENTS_CHECK(Float,
4090 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004091EXTERNAL_ELEMENTS_CHECK(Double,
4092 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004093EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004094
4095
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004096bool JSObject::HasNamedInterceptor() {
4097 return map()->has_named_interceptor();
4098}
4099
4100
4101bool JSObject::HasIndexedInterceptor() {
4102 return map()->has_indexed_interceptor();
4103}
4104
4105
ager@chromium.org5c838252010-02-19 08:53:10 +00004106bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004107 bool result = elements()->IsFixedArray() ||
4108 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004109 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004110 return result;
4111}
4112
4113
lrn@chromium.org303ada72010-10-27 09:33:13 +00004114MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004115 ASSERT(HasFastElements());
4116 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004117 Isolate* isolate = GetIsolate();
4118 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004119 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004120 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4121 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004122 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4123 return maybe_writable_elems;
4124 }
4125 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004126 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004127 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004128 return writable_elems;
4129}
4130
4131
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004132StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004134 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004135}
4136
4137
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004138NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004139 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004140 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004141}
4142
4143
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004144bool String::IsHashFieldComputed(uint32_t field) {
4145 return (field & kHashNotComputedMask) == 0;
4146}
4147
4148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004149bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004150 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004151}
4152
4153
4154uint32_t String::Hash() {
4155 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004156 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004157 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004158 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004159 return ComputeAndSetHash();
4160}
4161
4162
ager@chromium.org7c537e22008-10-16 08:43:32 +00004163StringHasher::StringHasher(int length)
4164 : length_(length),
4165 raw_running_hash_(0),
4166 array_index_(0),
4167 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4168 is_first_char_(true),
4169 is_valid_(true) { }
4170
4171
4172bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004173 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004174}
4175
4176
4177void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004178 // Use the Jenkins one-at-a-time hash function to update the hash
4179 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004180 raw_running_hash_ += c;
4181 raw_running_hash_ += (raw_running_hash_ << 10);
4182 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004183 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004184 if (is_array_index_) {
4185 if (c < '0' || c > '9') {
4186 is_array_index_ = false;
4187 } else {
4188 int d = c - '0';
4189 if (is_first_char_) {
4190 is_first_char_ = false;
4191 if (c == '0' && length_ > 1) {
4192 is_array_index_ = false;
4193 return;
4194 }
4195 }
4196 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4197 is_array_index_ = false;
4198 } else {
4199 array_index_ = array_index_ * 10 + d;
4200 }
4201 }
4202 }
4203}
4204
4205
4206void StringHasher::AddCharacterNoIndex(uc32 c) {
4207 ASSERT(!is_array_index());
4208 raw_running_hash_ += c;
4209 raw_running_hash_ += (raw_running_hash_ << 10);
4210 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4211}
4212
4213
4214uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004215 // Get the calculated raw hash value and do some more bit ops to distribute
4216 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004217 uint32_t result = raw_running_hash_;
4218 result += (result << 3);
4219 result ^= (result >> 11);
4220 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004221 if (result == 0) {
4222 result = 27;
4223 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004224 return result;
4225}
4226
4227
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004228template <typename schar>
4229uint32_t HashSequentialString(const schar* chars, int length) {
4230 StringHasher hasher(length);
4231 if (!hasher.has_trivial_hash()) {
4232 int i;
4233 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4234 hasher.AddCharacter(chars[i]);
4235 }
4236 for (; i < length; i++) {
4237 hasher.AddCharacterNoIndex(chars[i]);
4238 }
4239 }
4240 return hasher.GetHashField();
4241}
4242
4243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004244bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004245 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004246 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4247 return false;
4248 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004249 return SlowAsArrayIndex(index);
4250}
4251
4252
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004253Object* JSReceiver::GetPrototype() {
4254 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004255}
4256
4257
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004258bool JSReceiver::HasProperty(String* name) {
4259 if (IsJSProxy()) {
4260 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4261 }
4262 return GetPropertyAttribute(name) != ABSENT;
4263}
4264
4265
4266bool JSReceiver::HasLocalProperty(String* name) {
4267 if (IsJSProxy()) {
4268 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4269 }
4270 return GetLocalPropertyAttribute(name) != ABSENT;
4271}
4272
4273
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004274PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004275 return GetPropertyAttributeWithReceiver(this, key);
4276}
4277
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004278// TODO(504): this may be useful in other places too where JSGlobalProxy
4279// is used.
4280Object* JSObject::BypassGlobalProxy() {
4281 if (IsJSGlobalProxy()) {
4282 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004283 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004284 ASSERT(proto->IsJSGlobalObject());
4285 return proto;
4286 }
4287 return this;
4288}
4289
4290
4291bool JSObject::HasHiddenPropertiesObject() {
4292 ASSERT(!IsJSGlobalProxy());
4293 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004294 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004295 false) != ABSENT;
4296}
4297
4298
4299Object* JSObject::GetHiddenPropertiesObject() {
4300 ASSERT(!IsJSGlobalProxy());
4301 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004302 // You can't install a getter on a property indexed by the hidden symbol,
4303 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4304 // object.
4305 Object* result =
4306 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004307 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004308 &attributes)->ToObjectUnchecked();
4309 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004310}
4311
4312
lrn@chromium.org303ada72010-10-27 09:33:13 +00004313MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004314 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004315 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004316 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004317 DONT_ENUM,
4318 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004319}
4320
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004321
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004322bool JSObject::HasHiddenProperties() {
4323 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4324}
4325
4326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004327bool JSObject::HasElement(uint32_t index) {
4328 return HasElementWithReceiver(this, index);
4329}
4330
4331
4332bool AccessorInfo::all_can_read() {
4333 return BooleanBit::get(flag(), kAllCanReadBit);
4334}
4335
4336
4337void AccessorInfo::set_all_can_read(bool value) {
4338 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4339}
4340
4341
4342bool AccessorInfo::all_can_write() {
4343 return BooleanBit::get(flag(), kAllCanWriteBit);
4344}
4345
4346
4347void AccessorInfo::set_all_can_write(bool value) {
4348 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4349}
4350
4351
ager@chromium.org870a0b62008-11-04 11:43:05 +00004352bool AccessorInfo::prohibits_overwriting() {
4353 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4354}
4355
4356
4357void AccessorInfo::set_prohibits_overwriting(bool value) {
4358 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4359}
4360
4361
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004362PropertyAttributes AccessorInfo::property_attributes() {
4363 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4364}
4365
4366
4367void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4368 ASSERT(AttributesField::is_valid(attributes));
4369 int rest_value = flag()->value() & ~AttributesField::mask();
4370 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4371}
4372
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004373
4374template<typename Shape, typename Key>
4375void Dictionary<Shape, Key>::SetEntry(int entry,
4376 Object* key,
4377 Object* value) {
4378 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4379}
4380
4381
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004382template<typename Shape, typename Key>
4383void Dictionary<Shape, Key>::SetEntry(int entry,
4384 Object* key,
4385 Object* value,
4386 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004387 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004388 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004389 AssertNoAllocation no_gc;
4390 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004391 FixedArray::set(index, key, mode);
4392 FixedArray::set(index+1, value, mode);
4393 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004394}
4395
4396
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004397bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4398 ASSERT(other->IsNumber());
4399 return key == static_cast<uint32_t>(other->Number());
4400}
4401
4402
4403uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4404 return ComputeIntegerHash(key);
4405}
4406
4407
4408uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4409 ASSERT(other->IsNumber());
4410 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4411}
4412
4413
4414MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4415 return Isolate::Current()->heap()->NumberFromUint32(key);
4416}
4417
4418
4419bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4420 // We know that all entries in a hash table had their hash keys created.
4421 // Use that knowledge to have fast failure.
4422 if (key->Hash() != String::cast(other)->Hash()) return false;
4423 return key->Equals(String::cast(other));
4424}
4425
4426
4427uint32_t StringDictionaryShape::Hash(String* key) {
4428 return key->Hash();
4429}
4430
4431
4432uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4433 return String::cast(other)->Hash();
4434}
4435
4436
4437MaybeObject* StringDictionaryShape::AsObject(String* key) {
4438 return key;
4439}
4440
4441
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004442bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4443 return key == JSObject::cast(other);
4444}
4445
4446
4447uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4448 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4449 ASSERT(!maybe_hash->IsFailure());
4450 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4451}
4452
4453
4454uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4455 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4456 JSObject::OMIT_CREATION);
4457 ASSERT(!maybe_hash->IsFailure());
4458 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4459}
4460
4461
4462MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4463 return key;
4464}
4465
4466
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004467void ObjectHashTable::RemoveEntry(int entry) {
4468 RemoveEntry(entry, GetHeap());
4469}
4470
4471
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004472void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004473 // No write barrier is needed since empty_fixed_array is not in new space.
4474 // Please note this function is used during marking:
4475 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004476 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4477 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004478}
4479
4480
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004481void JSArray::EnsureSize(int required_size) {
4482 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004483 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004484 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4485 if (elts->length() < required_size) {
4486 // Doubling in size would be overkill, but leave some slack to avoid
4487 // constantly growing.
4488 Expand(required_size + (required_size >> 3));
4489 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004490 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004491 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4492 // Expand will allocate a new backing store in new space even if the size
4493 // we asked for isn't larger than what we had before.
4494 Expand(required_size);
4495 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004496}
4497
4498
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004499void JSArray::set_length(Smi* length) {
4500 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4501}
4502
4503
ager@chromium.org7c537e22008-10-16 08:43:32 +00004504void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004505 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004506 set_elements(storage);
4507}
4508
4509
lrn@chromium.org303ada72010-10-27 09:33:13 +00004510MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004511 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004512 return GetHeap()->CopyFixedArray(this);
4513}
4514
4515
4516Relocatable::Relocatable(Isolate* isolate) {
4517 ASSERT(isolate == Isolate::Current());
4518 isolate_ = isolate;
4519 prev_ = isolate->relocatable_top();
4520 isolate->set_relocatable_top(this);
4521}
4522
4523
4524Relocatable::~Relocatable() {
4525 ASSERT(isolate_ == Isolate::Current());
4526 ASSERT_EQ(isolate_->relocatable_top(), this);
4527 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004528}
4529
4530
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004531int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4532 return map->instance_size();
4533}
4534
4535
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004536void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004537 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004538 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004539}
4540
4541
4542template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004543void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004544 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004545 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004546}
4547
4548
4549void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4550 typedef v8::String::ExternalAsciiStringResource Resource;
4551 v->VisitExternalAsciiString(
4552 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4553}
4554
4555
4556template<typename StaticVisitor>
4557void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4558 typedef v8::String::ExternalAsciiStringResource Resource;
4559 StaticVisitor::VisitExternalAsciiString(
4560 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4561}
4562
4563
4564void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4565 typedef v8::String::ExternalStringResource Resource;
4566 v->VisitExternalTwoByteString(
4567 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4568}
4569
4570
4571template<typename StaticVisitor>
4572void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4573 typedef v8::String::ExternalStringResource Resource;
4574 StaticVisitor::VisitExternalTwoByteString(
4575 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4576}
4577
4578#define SLOT_ADDR(obj, offset) \
4579 reinterpret_cast<Object**>((obj)->address() + offset)
4580
4581template<int start_offset, int end_offset, int size>
4582void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4583 HeapObject* obj,
4584 ObjectVisitor* v) {
4585 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4586}
4587
4588
4589template<int start_offset>
4590void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4591 int object_size,
4592 ObjectVisitor* v) {
4593 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4594}
4595
4596#undef SLOT_ADDR
4597
4598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004599#undef CAST_ACCESSOR
4600#undef INT_ACCESSORS
4601#undef SMI_ACCESSORS
4602#undef ACCESSORS
4603#undef FIELD_ADDR
4604#undef READ_FIELD
4605#undef WRITE_FIELD
4606#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004607#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004608#undef READ_MEMADDR_FIELD
4609#undef WRITE_MEMADDR_FIELD
4610#undef READ_DOUBLE_FIELD
4611#undef WRITE_DOUBLE_FIELD
4612#undef READ_INT_FIELD
4613#undef WRITE_INT_FIELD
4614#undef READ_SHORT_FIELD
4615#undef WRITE_SHORT_FIELD
4616#undef READ_BYTE_FIELD
4617#undef WRITE_BYTE_FIELD
4618
4619
4620} } // namespace v8::internal
4621
4622#endif // V8_OBJECTS_INL_H_