blob: e5caa073d48fbc6b97d841911e3465a08e5773ec [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
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000042#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
kasperl@chromium.org71affb52009-05-26 05:44:31 +000047namespace v8 {
48namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50PropertyDetails::PropertyDetails(Smi* smi) {
51 value_ = smi->value();
52}
53
54
55Smi* PropertyDetails::AsSmi() {
56 return Smi::FromInt(value_);
57}
58
59
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000060PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000061 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000062 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
83 }
84
85
86// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
87#define ACCESSORS_GCSAFE(holder, name, type, offset) \
88 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
89 void holder::set_##name(type* value, WriteBarrierMode mode) { \
90 WRITE_FIELD(this, offset, value); \
91 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 }
93
94
95#define SMI_ACCESSORS(holder, name, offset) \
96 int holder::name() { \
97 Object* value = READ_FIELD(this, offset); \
98 return Smi::cast(value)->value(); \
99 } \
100 void holder::set_##name(int value) { \
101 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
102 }
103
104
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000105#define BOOL_GETTER(holder, field, name, offset) \
106 bool holder::name() { \
107 return BooleanBit::get(field(), offset); \
108 } \
109
110
111#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 bool holder::name() { \
113 return BooleanBit::get(field(), offset); \
114 } \
115 void holder::set_##name(bool value) { \
116 set_##field(BooleanBit::set(field(), offset, value)); \
117 }
118
119
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000120bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
121 // There is a constraint on the object; check.
122 if (!this->IsJSObject()) return false;
123 // Fetch the constructor function of the object.
124 Object* cons_obj = JSObject::cast(this)->map()->constructor();
125 if (!cons_obj->IsJSFunction()) return false;
126 JSFunction* fun = JSFunction::cast(cons_obj);
127 // Iterate through the chain of inheriting function templates to
128 // see if the required one occurs.
129 for (Object* type = fun->shared()->function_data();
130 type->IsFunctionTemplateInfo();
131 type = FunctionTemplateInfo::cast(type)->parent_template()) {
132 if (type == expected) return true;
133 }
134 // Didn't find the required type in the inheritance chain.
135 return false;
136}
137
138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139bool Object::IsSmi() {
140 return HAS_SMI_TAG(this);
141}
142
143
144bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000145 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146}
147
148
149bool Object::IsHeapNumber() {
150 return Object::IsHeapObject()
151 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
152}
153
154
155bool Object::IsString() {
156 return Object::IsHeapObject()
157 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
158}
159
160
ager@chromium.org870a0b62008-11-04 11:43:05 +0000161bool Object::IsSymbol() {
162 if (!this->IsHeapObject()) return false;
163 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000164 // Because the symbol tag is non-zero and no non-string types have the
165 // symbol bit set we can test for symbols with a very simple test
166 // operation.
167 ASSERT(kSymbolTag != 0);
168 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
169 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170}
171
172
173bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000174 if (!this->IsHeapObject()) return false;
175 uint32_t type = HeapObject::cast(this)->map()->instance_type();
176 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
177 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000178}
179
180
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181bool Object::IsSeqString() {
182 if (!IsString()) return false;
183 return StringShape(String::cast(this)).IsSequential();
184}
185
186
187bool Object::IsSeqAsciiString() {
188 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000189 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000190 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191}
192
193
194bool Object::IsSeqTwoByteString() {
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)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198}
199
200
201bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202 if (!IsString()) return false;
203 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204}
205
206
207bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000209 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000210 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211}
212
213
214bool Object::IsExternalTwoByteString() {
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)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000218}
219
220
ager@chromium.org870a0b62008-11-04 11:43:05 +0000221StringShape::StringShape(String* str)
222 : type_(str->map()->instance_type()) {
223 set_valid();
224 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225}
226
227
ager@chromium.org870a0b62008-11-04 11:43:05 +0000228StringShape::StringShape(Map* map)
229 : type_(map->instance_type()) {
230 set_valid();
231 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232}
233
234
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235StringShape::StringShape(InstanceType t)
236 : type_(static_cast<uint32_t>(t)) {
237 set_valid();
238 ASSERT((type_ & kIsNotStringMask) == kStringTag);
239}
240
241
242bool StringShape::IsSymbol() {
243 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000244 ASSERT(kSymbolTag != 0);
245 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000246}
247
248
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249bool String::IsAsciiRepresentation() {
250 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252}
253
254
ager@chromium.org5ec48922009-05-05 07:25:34 +0000255bool String::IsTwoByteRepresentation() {
256 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000257 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000258}
259
260
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000261bool String::HasOnlyAsciiChars() {
262 uint32_t type = map()->instance_type();
263 return (type & kStringEncodingMask) == kAsciiStringTag ||
264 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268bool StringShape::IsCons() {
269 return (type_ & kStringRepresentationMask) == kConsStringTag;
270}
271
272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273bool StringShape::IsExternal() {
274 return (type_ & kStringRepresentationMask) == kExternalStringTag;
275}
276
277
278bool StringShape::IsSequential() {
279 return (type_ & kStringRepresentationMask) == kSeqStringTag;
280}
281
282
283StringRepresentationTag StringShape::representation_tag() {
284 uint32_t tag = (type_ & kStringRepresentationMask);
285 return static_cast<StringRepresentationTag>(tag);
286}
287
288
289uint32_t StringShape::full_representation_tag() {
290 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
291}
292
293
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000294STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
295 Internals::kFullStringRepresentationMask);
296
297
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298bool StringShape::IsSequentialAscii() {
299 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305}
306
307
308bool StringShape::IsExternalAscii() {
309 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315}
316
317
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000318STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
319 Internals::kExternalTwoByteRepresentationTag);
320
321
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000322uc32 FlatStringReader::Get(int index) {
323 ASSERT(0 <= index && index <= length_);
324 if (is_ascii_) {
325 return static_cast<const byte*>(start_)[index];
326 } else {
327 return static_cast<const uc16*>(start_)[index];
328 }
329}
330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332bool Object::IsNumber() {
333 return IsSmi() || IsHeapNumber();
334}
335
336
337bool Object::IsByteArray() {
338 return Object::IsHeapObject()
339 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
340}
341
342
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000343bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000344 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000345 HeapObject::cast(this)->map()->instance_type() ==
346 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000347}
348
349
ager@chromium.org3811b432009-10-28 14:53:37 +0000350bool Object::IsExternalArray() {
351 if (!Object::IsHeapObject())
352 return false;
353 InstanceType instance_type =
354 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000355 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
356 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000357}
358
359
360bool Object::IsExternalByteArray() {
361 return Object::IsHeapObject() &&
362 HeapObject::cast(this)->map()->instance_type() ==
363 EXTERNAL_BYTE_ARRAY_TYPE;
364}
365
366
367bool Object::IsExternalUnsignedByteArray() {
368 return Object::IsHeapObject() &&
369 HeapObject::cast(this)->map()->instance_type() ==
370 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
371}
372
373
374bool Object::IsExternalShortArray() {
375 return Object::IsHeapObject() &&
376 HeapObject::cast(this)->map()->instance_type() ==
377 EXTERNAL_SHORT_ARRAY_TYPE;
378}
379
380
381bool Object::IsExternalUnsignedShortArray() {
382 return Object::IsHeapObject() &&
383 HeapObject::cast(this)->map()->instance_type() ==
384 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
385}
386
387
388bool Object::IsExternalIntArray() {
389 return Object::IsHeapObject() &&
390 HeapObject::cast(this)->map()->instance_type() ==
391 EXTERNAL_INT_ARRAY_TYPE;
392}
393
394
395bool Object::IsExternalUnsignedIntArray() {
396 return Object::IsHeapObject() &&
397 HeapObject::cast(this)->map()->instance_type() ==
398 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
399}
400
401
402bool Object::IsExternalFloatArray() {
403 return Object::IsHeapObject() &&
404 HeapObject::cast(this)->map()->instance_type() ==
405 EXTERNAL_FLOAT_ARRAY_TYPE;
406}
407
408
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000409bool Object::IsExternalDoubleArray() {
410 return Object::IsHeapObject() &&
411 HeapObject::cast(this)->map()->instance_type() ==
412 EXTERNAL_DOUBLE_ARRAY_TYPE;
413}
414
415
lrn@chromium.org303ada72010-10-27 09:33:13 +0000416bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417 return HAS_FAILURE_TAG(this);
418}
419
420
lrn@chromium.org303ada72010-10-27 09:33:13 +0000421bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422 return HAS_FAILURE_TAG(this)
423 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
424}
425
426
lrn@chromium.org303ada72010-10-27 09:33:13 +0000427bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000428 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000429 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000430}
431
432
lrn@chromium.org303ada72010-10-27 09:33:13 +0000433bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434 return this == Failure::Exception();
435}
436
437
lrn@chromium.org303ada72010-10-27 09:33:13 +0000438bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000439 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000440}
441
442
443Failure* Failure::cast(MaybeObject* obj) {
444 ASSERT(HAS_FAILURE_TAG(obj));
445 return reinterpret_cast<Failure*>(obj);
446}
447
448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000449bool Object::IsJSObject() {
450 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000451 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000452}
453
454
ager@chromium.org32912102009-01-16 10:38:43 +0000455bool Object::IsJSContextExtensionObject() {
456 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000457 && (HeapObject::cast(this)->map()->instance_type() ==
458 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000459}
460
461
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462bool Object::IsMap() {
463 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000464 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465}
466
467
468bool Object::IsFixedArray() {
469 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000470 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471}
472
473
474bool Object::IsDescriptorArray() {
475 return IsFixedArray();
476}
477
478
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479bool Object::IsDeoptimizationInputData() {
480 // Must be a fixed array.
481 if (!IsFixedArray()) return false;
482
483 // There's no sure way to detect the difference between a fixed array and
484 // a deoptimization data array. Since this is used for asserts we can
485 // check that the length is zero or else the fixed size plus a multiple of
486 // the entry size.
487 int length = FixedArray::cast(this)->length();
488 if (length == 0) return true;
489
490 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
491 return length >= 0 &&
492 length % DeoptimizationInputData::kDeoptEntrySize == 0;
493}
494
495
496bool Object::IsDeoptimizationOutputData() {
497 if (!IsFixedArray()) return false;
498 // There's actually no way to see the difference between a fixed array and
499 // a deoptimization data array. Since this is used for asserts we can check
500 // that the length is plausible though.
501 if (FixedArray::cast(this)->length() % 2 != 0) return false;
502 return true;
503}
504
505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000506bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000507 if (Object::IsHeapObject()) {
508 Heap* heap = HeapObject::cast(this)->GetHeap();
509 return (HeapObject::cast(this)->map() == heap->context_map() ||
510 HeapObject::cast(this)->map() == heap->catch_context_map() ||
511 HeapObject::cast(this)->map() == heap->global_context_map());
512 }
513 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514}
515
516
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000517bool Object::IsCatchContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000518 return Object::IsHeapObject() &&
519 HeapObject::cast(this)->map() ==
520 HeapObject::cast(this)->GetHeap()->catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000521}
522
523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000525 return Object::IsHeapObject() &&
526 HeapObject::cast(this)->map() ==
527 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528}
529
530
531bool Object::IsJSFunction() {
532 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000533 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534}
535
536
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000537template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538 return obj->IsJSFunction();
539}
540
541
542bool Object::IsCode() {
543 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000544 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000545}
546
547
548bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550 return Object::IsHeapObject()
551 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
552}
553
554
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000555bool Object::IsJSGlobalPropertyCell() {
556 return Object::IsHeapObject()
557 && HeapObject::cast(this)->map()->instance_type()
558 == JS_GLOBAL_PROPERTY_CELL_TYPE;
559}
560
561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000562bool Object::IsSharedFunctionInfo() {
563 return Object::IsHeapObject() &&
564 (HeapObject::cast(this)->map()->instance_type() ==
565 SHARED_FUNCTION_INFO_TYPE);
566}
567
568
569bool Object::IsJSValue() {
570 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000571 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
572}
573
574
575bool Object::IsJSMessageObject() {
576 return Object::IsHeapObject()
577 && (HeapObject::cast(this)->map()->instance_type() ==
578 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000579}
580
581
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000582bool Object::IsStringWrapper() {
583 return IsJSValue() && JSValue::cast(this)->value()->IsString();
584}
585
586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587bool Object::IsProxy() {
588 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000589 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000590}
591
592
593bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000594 return IsOddball() &&
595 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596}
597
598
599bool Object::IsJSArray() {
600 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000601 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602}
603
604
ager@chromium.org236ad962008-09-25 09:45:57 +0000605bool Object::IsJSRegExp() {
606 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000607 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000608}
609
610
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000611template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612 return obj->IsJSArray();
613}
614
615
616bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000617 return Object::IsHeapObject() &&
618 HeapObject::cast(this)->map() ==
619 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
623bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000624 return IsHashTable() && this !=
625 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000630 return IsHashTable() && this ==
631 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
ager@chromium.orgac091b72010-05-05 07:34:42 +0000635bool Object::IsJSFunctionResultCache() {
636 if (!IsFixedArray()) return false;
637 FixedArray* self = FixedArray::cast(this);
638 int length = self->length();
639 if (length < JSFunctionResultCache::kEntriesIndex) return false;
640 if ((length - JSFunctionResultCache::kEntriesIndex)
641 % JSFunctionResultCache::kEntrySize != 0) {
642 return false;
643 }
644#ifdef DEBUG
645 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
646#endif
647 return true;
648}
649
650
ricow@chromium.org65fae842010-08-25 15:26:24 +0000651bool Object::IsNormalizedMapCache() {
652 if (!IsFixedArray()) return false;
653 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
654 return false;
655 }
656#ifdef DEBUG
657 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
658#endif
659 return true;
660}
661
662
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000663bool Object::IsCompilationCacheTable() {
664 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000665}
666
667
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000668bool Object::IsCodeCacheHashTable() {
669 return IsHashTable();
670}
671
672
ager@chromium.org236ad962008-09-25 09:45:57 +0000673bool Object::IsMapCache() {
674 return IsHashTable();
675}
676
677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678bool Object::IsPrimitive() {
679 return IsOddball() || IsNumber() || IsString();
680}
681
682
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000683bool Object::IsJSGlobalProxy() {
684 bool result = IsHeapObject() &&
685 (HeapObject::cast(this)->map()->instance_type() ==
686 JS_GLOBAL_PROXY_TYPE);
687 ASSERT(!result || IsAccessCheckNeeded());
688 return result;
689}
690
691
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000692bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000693 if (!IsHeapObject()) return false;
694
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000695 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000696 return type == JS_GLOBAL_OBJECT_TYPE ||
697 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698}
699
700
701bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000702 return IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_OBJECT_TYPE);
705}
706
707
708bool Object::IsJSBuiltinsObject() {
709 return IsHeapObject() &&
710 (HeapObject::cast(this)->map()->instance_type() ==
711 JS_BUILTINS_OBJECT_TYPE);
712}
713
714
715bool Object::IsUndetectableObject() {
716 return IsHeapObject()
717 && HeapObject::cast(this)->map()->is_undetectable();
718}
719
720
721bool Object::IsAccessCheckNeeded() {
722 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000723 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724}
725
726
727bool Object::IsStruct() {
728 if (!IsHeapObject()) return false;
729 switch (HeapObject::cast(this)->map()->instance_type()) {
730#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
731 STRUCT_LIST(MAKE_STRUCT_CASE)
732#undef MAKE_STRUCT_CASE
733 default: return false;
734 }
735}
736
737
738#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
739 bool Object::Is##Name() { \
740 return Object::IsHeapObject() \
741 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
742 }
743 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
744#undef MAKE_STRUCT_PREDICATE
745
746
747bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000748 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000749}
750
751
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000753 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
754}
755
756
757bool Object::IsTheHole() {
758 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000759}
760
761
762bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000763 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000764}
765
766
767bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000768 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000769}
770
771
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000772bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000773 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000774}
775
776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777double Object::Number() {
778 ASSERT(IsNumber());
779 return IsSmi()
780 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
781 : reinterpret_cast<HeapNumber*>(this)->value();
782}
783
784
lrn@chromium.org303ada72010-10-27 09:33:13 +0000785MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786 if (IsSmi()) return this;
787 if (IsHeapNumber()) {
788 double value = HeapNumber::cast(this)->value();
789 int int_value = FastD2I(value);
790 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
791 return Smi::FromInt(int_value);
792 }
793 }
794 return Failure::Exception();
795}
796
797
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000798bool Object::HasSpecificClassOf(String* name) {
799 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
800}
801
802
lrn@chromium.org303ada72010-10-27 09:33:13 +0000803MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000804 // GetElement can trigger a getter which can cause allocation.
805 // This was not always the case. This ASSERT is here to catch
806 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000807 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808 return GetElementWithReceiver(this, index);
809}
810
811
lrn@chromium.org303ada72010-10-27 09:33:13 +0000812Object* Object::GetElementNoExceptionThrown(uint32_t index) {
813 MaybeObject* maybe = GetElementWithReceiver(this, index);
814 ASSERT(!maybe->IsFailure());
815 Object* result = NULL; // Initialization to please compiler.
816 maybe->ToObject(&result);
817 return result;
818}
819
820
821MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822 PropertyAttributes attributes;
823 return GetPropertyWithReceiver(this, key, &attributes);
824}
825
826
lrn@chromium.org303ada72010-10-27 09:33:13 +0000827MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 return GetPropertyWithReceiver(this, key, attributes);
829}
830
831
832#define FIELD_ADDR(p, offset) \
833 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
834
835#define READ_FIELD(p, offset) \
836 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
837
838#define WRITE_FIELD(p, offset, value) \
839 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
840
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000841// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000843 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000844
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000845// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000846// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000847#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000848 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000850 } else { \
851 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000852 ASSERT(heap->InNewSpace(object) || \
853 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000854 Page::FromAddress(object->address())-> \
855 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000856 }
857
lrn@chromium.org7516f052011-03-30 08:52:27 +0000858#ifndef V8_TARGET_ARCH_MIPS
859 #define READ_DOUBLE_FIELD(p, offset) \
860 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
861#else // V8_TARGET_ARCH_MIPS
862 // Prevent gcc from using load-double (mips ldc1) on (possibly)
863 // non-64-bit aligned HeapNumber::value.
864 static inline double read_double_field(HeapNumber* p, int offset) {
865 union conversion {
866 double d;
867 uint32_t u[2];
868 } c;
869 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
870 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
871 return c.d;
872 }
873 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
874#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875
lrn@chromium.org7516f052011-03-30 08:52:27 +0000876
877#ifndef V8_TARGET_ARCH_MIPS
878 #define WRITE_DOUBLE_FIELD(p, offset, value) \
879 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
880#else // V8_TARGET_ARCH_MIPS
881 // Prevent gcc from using store-double (mips sdc1) on (possibly)
882 // non-64-bit aligned HeapNumber::value.
883 static inline void write_double_field(HeapNumber* p, int offset,
884 double value) {
885 union conversion {
886 double d;
887 uint32_t u[2];
888 } c;
889 c.d = value;
890 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
891 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
892 }
893 #define WRITE_DOUBLE_FIELD(p, offset, value) \
894 write_double_field(p, offset, value)
895#endif // V8_TARGET_ARCH_MIPS
896
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897
898#define READ_INT_FIELD(p, offset) \
899 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
900
901#define WRITE_INT_FIELD(p, offset, value) \
902 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
903
ager@chromium.org3e875802009-06-29 08:26:34 +0000904#define READ_INTPTR_FIELD(p, offset) \
905 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INTPTR_FIELD(p, offset, value) \
908 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org7c537e22008-10-16 08:43:32 +0000910#define READ_UINT32_FIELD(p, offset) \
911 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_UINT32_FIELD(p, offset, value) \
914 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
915
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000916#define READ_SHORT_FIELD(p, offset) \
917 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_SHORT_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
921
922#define READ_BYTE_FIELD(p, offset) \
923 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_BYTE_FIELD(p, offset, value) \
926 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
927
928
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000929Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
930 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000931}
932
933
934int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000935 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000936}
937
938
939Smi* Smi::FromInt(int value) {
940 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000941 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000942 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000943 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000944 return reinterpret_cast<Smi*>(tagged_value);
945}
946
947
948Smi* Smi::FromIntptr(intptr_t value) {
949 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000950 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
951 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952}
953
954
955Failure::Type Failure::type() const {
956 return static_cast<Type>(value() & kFailureTypeTagMask);
957}
958
959
960bool Failure::IsInternalError() const {
961 return type() == INTERNAL_ERROR;
962}
963
964
965bool Failure::IsOutOfMemoryException() const {
966 return type() == OUT_OF_MEMORY_EXCEPTION;
967}
968
969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970AllocationSpace Failure::allocation_space() const {
971 ASSERT_EQ(RETRY_AFTER_GC, type());
972 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
973 & kSpaceTagMask);
974}
975
976
977Failure* Failure::InternalError() {
978 return Construct(INTERNAL_ERROR);
979}
980
981
982Failure* Failure::Exception() {
983 return Construct(EXCEPTION);
984}
985
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000986
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000987Failure* Failure::OutOfMemoryException() {
988 return Construct(OUT_OF_MEMORY_EXCEPTION);
989}
990
991
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000992intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000993 return static_cast<intptr_t>(
994 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000995}
996
997
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000998Failure* Failure::RetryAfterGC() {
999 return RetryAfterGC(NEW_SPACE);
1000}
1001
1002
1003Failure* Failure::RetryAfterGC(AllocationSpace space) {
1004 ASSERT((space & ~kSpaceTagMask) == 0);
1005 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001006}
1007
1008
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001009Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001010 uintptr_t info =
1011 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001012 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001013 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001014}
1015
1016
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001017bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001018#ifdef DEBUG
1019 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1020#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001021
1022#ifdef V8_TARGET_ARCH_X64
1023 // To be representable as a long smi, the value must be a 32-bit integer.
1024 bool result = (value == static_cast<int32_t>(value));
1025#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026 // To be representable as an tagged small integer, the two
1027 // most-significant bits of 'value' must be either 00 or 11 due to
1028 // sign-extension. To check this we add 01 to the two
1029 // most-significant bits, and check if the most-significant bit is 0
1030 //
1031 // CAUTION: The original code below:
1032 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1033 // may lead to incorrect results according to the C language spec, and
1034 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1035 // compiler may produce undefined results in case of signed integer
1036 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001037 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001038#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001039 ASSERT(result == in_range);
1040 return result;
1041}
1042
1043
kasper.lund7276f142008-07-30 08:49:36 +00001044MapWord MapWord::FromMap(Map* map) {
1045 return MapWord(reinterpret_cast<uintptr_t>(map));
1046}
1047
1048
1049Map* MapWord::ToMap() {
1050 return reinterpret_cast<Map*>(value_);
1051}
1052
1053
1054bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001055 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001056}
1057
1058
1059MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001060 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1061 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065HeapObject* MapWord::ToForwardingAddress() {
1066 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001067 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071bool MapWord::IsMarked() {
1072 return (value_ & kMarkingMask) == 0;
1073}
1074
1075
1076void MapWord::SetMark() {
1077 value_ &= ~kMarkingMask;
1078}
1079
1080
1081void MapWord::ClearMark() {
1082 value_ |= kMarkingMask;
1083}
1084
1085
1086bool MapWord::IsOverflowed() {
1087 return (value_ & kOverflowMask) != 0;
1088}
1089
1090
1091void MapWord::SetOverflow() {
1092 value_ |= kOverflowMask;
1093}
1094
1095
1096void MapWord::ClearOverflow() {
1097 value_ &= ~kOverflowMask;
1098}
1099
1100
1101MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1102 // Offset is the distance in live bytes from the first live object in the
1103 // same page. The offset between two objects in the same page should not
1104 // exceed the object area size of a page.
1105 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1106
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001107 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001108 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1109
1110 Page* map_page = Page::FromAddress(map_address);
1111 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1112
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001113 uintptr_t map_page_offset =
1114 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001115
1116 uintptr_t encoding =
1117 (compact_offset << kForwardingOffsetShift) |
1118 (map_page_offset << kMapPageOffsetShift) |
1119 (map_page->mc_page_index << kMapPageIndexShift);
1120 return MapWord(encoding);
1121}
1122
1123
1124Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001125 int map_page_index =
1126 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001127 ASSERT_MAP_PAGE_INDEX(map_page_index);
1128
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001129 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001130 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1131 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001132
1133 return (map_space->PageAddress(map_page_index) + map_page_offset);
1134}
1135
1136
1137int MapWord::DecodeOffset() {
1138 // The offset field is represented in the kForwardingOffsetBits
1139 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001140 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1141 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1142 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001143}
1144
1145
1146MapWord MapWord::FromEncodedAddress(Address address) {
1147 return MapWord(reinterpret_cast<uintptr_t>(address));
1148}
1149
1150
1151Address MapWord::ToEncodedAddress() {
1152 return reinterpret_cast<Address>(value_);
1153}
1154
1155
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001156#ifdef DEBUG
1157void HeapObject::VerifyObjectField(int offset) {
1158 VerifyPointer(READ_FIELD(this, offset));
1159}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001160
1161void HeapObject::VerifySmiField(int offset) {
1162 ASSERT(READ_FIELD(this, offset)->IsSmi());
1163}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164#endif
1165
1166
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001167Heap* HeapObject::GetHeap() {
1168 // During GC, the map pointer in HeapObject is used in various ways that
1169 // prevent us from retrieving Heap from the map.
1170 // Assert that we are not in GC, implement GC code in a way that it doesn't
1171 // pull heap from the map.
1172 ASSERT(HEAP->is_safe_to_read_maps());
1173 return map()->heap();
1174}
1175
1176
1177Isolate* HeapObject::GetIsolate() {
1178 return GetHeap()->isolate();
1179}
1180
1181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001182Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001183 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001184}
1185
1186
1187void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001188 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001189}
1190
1191
kasper.lund7276f142008-07-30 08:49:36 +00001192MapWord HeapObject::map_word() {
1193 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1194}
1195
1196
1197void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001198 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001199 // here.
1200 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1201}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202
1203
1204HeapObject* HeapObject::FromAddress(Address address) {
1205 ASSERT_TAG_ALIGNED(address);
1206 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1207}
1208
1209
1210Address HeapObject::address() {
1211 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1212}
1213
1214
1215int HeapObject::Size() {
1216 return SizeFromMap(map());
1217}
1218
1219
1220void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1221 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1222 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1223}
1224
1225
1226void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1227 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1228}
1229
1230
kasper.lund7276f142008-07-30 08:49:36 +00001231bool HeapObject::IsMarked() {
1232 return map_word().IsMarked();
1233}
1234
1235
1236void HeapObject::SetMark() {
1237 ASSERT(!IsMarked());
1238 MapWord first_word = map_word();
1239 first_word.SetMark();
1240 set_map_word(first_word);
1241}
1242
1243
1244void HeapObject::ClearMark() {
1245 ASSERT(IsMarked());
1246 MapWord first_word = map_word();
1247 first_word.ClearMark();
1248 set_map_word(first_word);
1249}
1250
1251
1252bool HeapObject::IsOverflowed() {
1253 return map_word().IsOverflowed();
1254}
1255
1256
1257void HeapObject::SetOverflow() {
1258 MapWord first_word = map_word();
1259 first_word.SetOverflow();
1260 set_map_word(first_word);
1261}
1262
1263
1264void HeapObject::ClearOverflow() {
1265 ASSERT(IsOverflowed());
1266 MapWord first_word = map_word();
1267 first_word.ClearOverflow();
1268 set_map_word(first_word);
1269}
1270
1271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001272double HeapNumber::value() {
1273 return READ_DOUBLE_FIELD(this, kValueOffset);
1274}
1275
1276
1277void HeapNumber::set_value(double value) {
1278 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1279}
1280
1281
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001282int HeapNumber::get_exponent() {
1283 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1284 kExponentShift) - kExponentBias;
1285}
1286
1287
1288int HeapNumber::get_sign() {
1289 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1290}
1291
1292
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001293ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001294
1295
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001296HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001297 Object* array = READ_FIELD(this, kElementsOffset);
1298 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001299 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001300 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001301}
1302
1303
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001304void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001305 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001306 (value->map() == GetHeap()->fixed_array_map() ||
1307 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001308 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001309 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001310 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001311 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001312}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001313
1314
1315void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001316 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1317 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001318}
1319
1320
1321void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001322 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001323 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1324 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001325}
1326
1327
lrn@chromium.org303ada72010-10-27 09:33:13 +00001328MaybeObject* JSObject::ResetElements() {
1329 Object* obj;
1330 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1331 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1332 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001333 set_map(Map::cast(obj));
1334 initialize_elements();
1335 return this;
1336}
1337
1338
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001339ACCESSORS(Oddball, to_string, String, kToStringOffset)
1340ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1341
1342
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001343byte Oddball::kind() {
1344 return READ_BYTE_FIELD(this, kKindOffset);
1345}
1346
1347
1348void Oddball::set_kind(byte value) {
1349 WRITE_BYTE_FIELD(this, kKindOffset, value);
1350}
1351
1352
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001353Object* JSGlobalPropertyCell::value() {
1354 return READ_FIELD(this, kValueOffset);
1355}
1356
1357
1358void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1359 // The write barrier is not used for global property cells.
1360 ASSERT(!val->IsJSGlobalPropertyCell());
1361 WRITE_FIELD(this, kValueOffset, val);
1362}
1363
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001364
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001365int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001366 InstanceType type = map()->instance_type();
1367 // Check for the most common kind of JavaScript object before
1368 // falling into the generic switch. This speeds up the internal
1369 // field operations considerably on average.
1370 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1371 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001372 case JS_GLOBAL_PROXY_TYPE:
1373 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001374 case JS_GLOBAL_OBJECT_TYPE:
1375 return JSGlobalObject::kSize;
1376 case JS_BUILTINS_OBJECT_TYPE:
1377 return JSBuiltinsObject::kSize;
1378 case JS_FUNCTION_TYPE:
1379 return JSFunction::kSize;
1380 case JS_VALUE_TYPE:
1381 return JSValue::kSize;
1382 case JS_ARRAY_TYPE:
1383 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001384 case JS_REGEXP_TYPE:
1385 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001386 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001387 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001388 case JS_MESSAGE_OBJECT_TYPE:
1389 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001390 default:
1391 UNREACHABLE();
1392 return 0;
1393 }
1394}
1395
1396
1397int JSObject::GetInternalFieldCount() {
1398 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001399 // Make sure to adjust for the number of in-object properties. These
1400 // properties do contribute to the size, but are not internal fields.
1401 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1402 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001403}
1404
1405
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001406int JSObject::GetInternalFieldOffset(int index) {
1407 ASSERT(index < GetInternalFieldCount() && index >= 0);
1408 return GetHeaderSize() + (kPointerSize * index);
1409}
1410
1411
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001412Object* JSObject::GetInternalField(int index) {
1413 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001414 // Internal objects do follow immediately after the header, whereas in-object
1415 // properties are at the end of the object. Therefore there is no need
1416 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1418}
1419
1420
1421void JSObject::SetInternalField(int index, Object* value) {
1422 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001423 // Internal objects do follow immediately after the header, whereas in-object
1424 // properties are at the end of the object. Therefore there is no need
1425 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426 int offset = GetHeaderSize() + (kPointerSize * index);
1427 WRITE_FIELD(this, offset, value);
1428 WRITE_BARRIER(this, offset);
1429}
1430
1431
ager@chromium.org7c537e22008-10-16 08:43:32 +00001432// Access fast-case object properties at index. The use of these routines
1433// is needed to correctly distinguish between properties stored in-object and
1434// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001435Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001436 // Adjust for the number of properties stored in the object.
1437 index -= map()->inobject_properties();
1438 if (index < 0) {
1439 int offset = map()->instance_size() + (index * kPointerSize);
1440 return READ_FIELD(this, offset);
1441 } else {
1442 ASSERT(index < properties()->length());
1443 return properties()->get(index);
1444 }
1445}
1446
1447
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001448Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001449 // Adjust for the number of properties stored in the object.
1450 index -= map()->inobject_properties();
1451 if (index < 0) {
1452 int offset = map()->instance_size() + (index * kPointerSize);
1453 WRITE_FIELD(this, offset, value);
1454 WRITE_BARRIER(this, offset);
1455 } else {
1456 ASSERT(index < properties()->length());
1457 properties()->set(index, value);
1458 }
1459 return value;
1460}
1461
1462
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001463int JSObject::GetInObjectPropertyOffset(int index) {
1464 // Adjust for the number of properties stored in the object.
1465 index -= map()->inobject_properties();
1466 ASSERT(index < 0);
1467 return map()->instance_size() + (index * kPointerSize);
1468}
1469
1470
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001471Object* JSObject::InObjectPropertyAt(int index) {
1472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 ASSERT(index < 0);
1475 int offset = map()->instance_size() + (index * kPointerSize);
1476 return READ_FIELD(this, offset);
1477}
1478
1479
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001480Object* JSObject::InObjectPropertyAtPut(int index,
1481 Object* value,
1482 WriteBarrierMode mode) {
1483 // Adjust for the number of properties stored in the object.
1484 index -= map()->inobject_properties();
1485 ASSERT(index < 0);
1486 int offset = map()->instance_size() + (index * kPointerSize);
1487 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001488 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001489 return value;
1490}
1491
1492
1493
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001494void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001495 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001497 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 }
1499}
1500
1501
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001502bool JSObject::HasFastProperties() {
1503 return !properties()->IsDictionary();
1504}
1505
1506
1507int JSObject::MaxFastProperties() {
1508 // Allow extra fast properties if the object has more than
1509 // kMaxFastProperties in-object properties. When this is the case,
1510 // it is very unlikely that the object is being used as a dictionary
1511 // and there is a good chance that allowing more map transitions
1512 // will be worth it.
1513 return Max(map()->inobject_properties(), kMaxFastProperties);
1514}
1515
1516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001517void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001518 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001519 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001520 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 }
1522}
1523
1524
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001525bool Object::ToArrayIndex(uint32_t* index) {
1526 if (IsSmi()) {
1527 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001528 if (value < 0) return false;
1529 *index = value;
1530 return true;
1531 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001532 if (IsHeapNumber()) {
1533 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001534 uint32_t uint_value = static_cast<uint32_t>(value);
1535 if (value == static_cast<double>(uint_value)) {
1536 *index = uint_value;
1537 return true;
1538 }
1539 }
1540 return false;
1541}
1542
1543
1544bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1545 if (!this->IsJSValue()) return false;
1546
1547 JSValue* js_value = JSValue::cast(this);
1548 if (!js_value->value()->IsString()) return false;
1549
1550 String* str = String::cast(js_value->value());
1551 if (index >= (uint32_t)str->length()) return false;
1552
1553 return true;
1554}
1555
1556
1557Object* FixedArray::get(int index) {
1558 ASSERT(index >= 0 && index < this->length());
1559 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1560}
1561
1562
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001563void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001564 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001565 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1566 int offset = kHeaderSize + index * kPointerSize;
1567 WRITE_FIELD(this, offset, value);
1568}
1569
1570
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001572 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 ASSERT(index >= 0 && index < this->length());
1574 int offset = kHeaderSize + index * kPointerSize;
1575 WRITE_FIELD(this, offset, value);
1576 WRITE_BARRIER(this, offset);
1577}
1578
1579
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001580WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001581 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001582 return UPDATE_WRITE_BARRIER;
1583}
1584
1585
1586void FixedArray::set(int index,
1587 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001588 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001589 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001590 ASSERT(index >= 0 && index < this->length());
1591 int offset = kHeaderSize + index * kPointerSize;
1592 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001593 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594}
1595
1596
1597void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001598 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001600 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1602}
1603
1604
1605void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001606 ASSERT(map() != HEAP->fixed_cow_array_map());
1607 set_undefined(GetHeap(), index);
1608}
1609
1610
1611void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001613 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001615 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616}
1617
1618
ager@chromium.org236ad962008-09-25 09:45:57 +00001619void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001620 set_null(GetHeap(), index);
1621}
1622
1623
1624void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001625 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001626 ASSERT(!heap->InNewSpace(heap->null_value()));
1627 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001628}
1629
1630
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001631void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001632 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001634 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1635 WRITE_FIELD(this,
1636 kHeaderSize + index * kPointerSize,
1637 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001638}
1639
1640
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001641void FixedArray::set_unchecked(int index, Smi* value) {
1642 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1643 int offset = kHeaderSize + index * kPointerSize;
1644 WRITE_FIELD(this, offset, value);
1645}
1646
1647
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001648void FixedArray::set_unchecked(Heap* heap,
1649 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001650 Object* value,
1651 WriteBarrierMode mode) {
1652 int offset = kHeaderSize + index * kPointerSize;
1653 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001654 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001655}
1656
1657
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001658void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001659 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001660 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1661 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001662}
1663
1664
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001665Object** FixedArray::data_start() {
1666 return HeapObject::RawField(this, kHeaderSize);
1667}
1668
1669
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001670bool DescriptorArray::IsEmpty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001671 ASSERT(this->length() > kFirstIndex ||
1672 this == HEAP->empty_descriptor_array());
1673 return length() <= kFirstIndex;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001674}
1675
1676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1678 Object* tmp = array->get(first);
1679 fast_set(array, first, array->get(second));
1680 fast_set(array, second, tmp);
1681}
1682
1683
1684int DescriptorArray::Search(String* name) {
1685 SLOW_ASSERT(IsSortedNoDuplicates());
1686
1687 // Check for empty descriptor array.
1688 int nof = number_of_descriptors();
1689 if (nof == 0) return kNotFound;
1690
1691 // Fast case: do linear search for small arrays.
1692 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001693 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001694 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695 }
1696
1697 // Slow case: perform binary search.
1698 return BinarySearch(name, 0, nof - 1);
1699}
1700
1701
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001702int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001703 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001704 if (number == DescriptorLookupCache::kAbsent) {
1705 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001706 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001707 }
1708 return number;
1709}
1710
1711
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712String* DescriptorArray::GetKey(int descriptor_number) {
1713 ASSERT(descriptor_number < number_of_descriptors());
1714 return String::cast(get(ToKeyIndex(descriptor_number)));
1715}
1716
1717
1718Object* DescriptorArray::GetValue(int descriptor_number) {
1719 ASSERT(descriptor_number < number_of_descriptors());
1720 return GetContentArray()->get(ToValueIndex(descriptor_number));
1721}
1722
1723
1724Smi* DescriptorArray::GetDetails(int descriptor_number) {
1725 ASSERT(descriptor_number < number_of_descriptors());
1726 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1727}
1728
1729
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001730PropertyType DescriptorArray::GetType(int descriptor_number) {
1731 ASSERT(descriptor_number < number_of_descriptors());
1732 return PropertyDetails(GetDetails(descriptor_number)).type();
1733}
1734
1735
1736int DescriptorArray::GetFieldIndex(int descriptor_number) {
1737 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1738}
1739
1740
1741JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1742 return JSFunction::cast(GetValue(descriptor_number));
1743}
1744
1745
1746Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1747 ASSERT(GetType(descriptor_number) == CALLBACKS);
1748 return GetValue(descriptor_number);
1749}
1750
1751
1752AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1753 ASSERT(GetType(descriptor_number) == CALLBACKS);
1754 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1755 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1756}
1757
1758
1759bool DescriptorArray::IsProperty(int descriptor_number) {
1760 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1761}
1762
1763
1764bool DescriptorArray::IsTransition(int descriptor_number) {
1765 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001766 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1767 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001768}
1769
1770
1771bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1772 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1773}
1774
1775
1776bool DescriptorArray::IsDontEnum(int descriptor_number) {
1777 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1778}
1779
1780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1782 desc->Init(GetKey(descriptor_number),
1783 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001784 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001785}
1786
1787
1788void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1789 // Range check.
1790 ASSERT(descriptor_number < number_of_descriptors());
1791
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001792 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001793 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1794 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001795
1796 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1797 FixedArray* content_array = GetContentArray();
1798 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1799 fast_set(content_array, ToDetailsIndex(descriptor_number),
1800 desc->GetDetails().AsSmi());
1801}
1802
1803
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001804void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1805 Descriptor desc;
1806 src->Get(src_index, &desc);
1807 Set(index, &desc);
1808}
1809
1810
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811void DescriptorArray::Swap(int first, int second) {
1812 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1813 FixedArray* content_array = GetContentArray();
1814 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1815 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1816}
1817
1818
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001819template<typename Shape, typename Key>
1820int HashTable<Shape, Key>::FindEntry(Key key) {
1821 return FindEntry(GetIsolate(), key);
1822}
1823
1824
1825// Find entry for key otherwise return kNotFound.
1826template<typename Shape, typename Key>
1827int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1828 uint32_t capacity = Capacity();
1829 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1830 uint32_t count = 1;
1831 // EnsureCapacity will guarantee the hash table is never full.
1832 while (true) {
1833 Object* element = KeyAt(entry);
1834 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1835 if (element != isolate->heap()->null_value() &&
1836 Shape::IsMatch(key, element)) return entry;
1837 entry = NextProbe(entry, count++, capacity);
1838 }
1839 return kNotFound;
1840}
1841
1842
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001843bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001844 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001845 if (!max_index_object->IsSmi()) return false;
1846 return 0 !=
1847 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1848}
1849
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001850uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001852 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001853 if (!max_index_object->IsSmi()) return 0;
1854 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1855 return value >> kRequiresSlowElementsTagSize;
1856}
1857
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001858void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001859 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001860}
1861
1862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863// ------------------------------------
1864// Cast operations
1865
1866
1867CAST_ACCESSOR(FixedArray)
1868CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869CAST_ACCESSOR(DeoptimizationInputData)
1870CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001871CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001872CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001873CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001874CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001875CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001876CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877CAST_ACCESSOR(String)
1878CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001879CAST_ACCESSOR(SeqAsciiString)
1880CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001882CAST_ACCESSOR(ExternalString)
1883CAST_ACCESSOR(ExternalAsciiString)
1884CAST_ACCESSOR(ExternalTwoByteString)
1885CAST_ACCESSOR(JSObject)
1886CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001887CAST_ACCESSOR(HeapObject)
1888CAST_ACCESSOR(HeapNumber)
1889CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001890CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891CAST_ACCESSOR(SharedFunctionInfo)
1892CAST_ACCESSOR(Map)
1893CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001894CAST_ACCESSOR(GlobalObject)
1895CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001896CAST_ACCESSOR(JSGlobalObject)
1897CAST_ACCESSOR(JSBuiltinsObject)
1898CAST_ACCESSOR(Code)
1899CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001900CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901CAST_ACCESSOR(Proxy)
1902CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001903CAST_ACCESSOR(ExternalArray)
1904CAST_ACCESSOR(ExternalByteArray)
1905CAST_ACCESSOR(ExternalUnsignedByteArray)
1906CAST_ACCESSOR(ExternalShortArray)
1907CAST_ACCESSOR(ExternalUnsignedShortArray)
1908CAST_ACCESSOR(ExternalIntArray)
1909CAST_ACCESSOR(ExternalUnsignedIntArray)
1910CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001911CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001912CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913CAST_ACCESSOR(Struct)
1914
1915
1916#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1917 STRUCT_LIST(MAKE_STRUCT_CAST)
1918#undef MAKE_STRUCT_CAST
1919
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001920
1921template <typename Shape, typename Key>
1922HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001923 ASSERT(obj->IsHashTable());
1924 return reinterpret_cast<HashTable*>(obj);
1925}
1926
1927
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001928SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1929SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1930
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001931INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932
1933
ager@chromium.orgac091b72010-05-05 07:34:42 +00001934SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001935
1936
1937uint32_t String::hash_field() {
1938 return READ_UINT32_FIELD(this, kHashFieldOffset);
1939}
1940
1941
1942void String::set_hash_field(uint32_t value) {
1943 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001944#if V8_HOST_ARCH_64_BIT
1945 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1946#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001947}
1948
1949
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001950bool String::Equals(String* other) {
1951 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001952 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1953 return false;
1954 }
1955 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956}
1957
1958
lrn@chromium.org303ada72010-10-27 09:33:13 +00001959MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001960 if (!StringShape(this).IsCons()) return this;
1961 ConsString* cons = ConsString::cast(this);
1962 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001963 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001967String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001968 MaybeObject* flat = TryFlatten(pretenure);
1969 Object* successfully_flattened;
1970 if (flat->ToObject(&successfully_flattened)) {
1971 return String::cast(successfully_flattened);
1972 }
1973 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001974}
1975
1976
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001977uint16_t String::Get(int index) {
1978 ASSERT(index >= 0 && index < length());
1979 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001980 case kSeqStringTag | kAsciiStringTag:
1981 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1982 case kSeqStringTag | kTwoByteStringTag:
1983 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1984 case kConsStringTag | kAsciiStringTag:
1985 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001986 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001987 case kExternalStringTag | kAsciiStringTag:
1988 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1989 case kExternalStringTag | kTwoByteStringTag:
1990 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991 default:
1992 break;
1993 }
1994
1995 UNREACHABLE();
1996 return 0;
1997}
1998
1999
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002000void String::Set(int index, uint16_t value) {
2001 ASSERT(index >= 0 && index < length());
2002 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002003
ager@chromium.org5ec48922009-05-05 07:25:34 +00002004 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002005 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2006 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002007}
2008
2009
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002010bool String::IsFlat() {
2011 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002012 case kConsStringTag: {
2013 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002014 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002015 return second->length() == 0;
2016 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002017 default:
2018 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019 }
2020}
2021
2022
ager@chromium.org7c537e22008-10-16 08:43:32 +00002023uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024 ASSERT(index >= 0 && index < length());
2025 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2026}
2027
2028
ager@chromium.org7c537e22008-10-16 08:43:32 +00002029void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2031 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2032 static_cast<byte>(value));
2033}
2034
2035
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037 return FIELD_ADDR(this, kHeaderSize);
2038}
2039
2040
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002041char* SeqAsciiString::GetChars() {
2042 return reinterpret_cast<char*>(GetCharsAddress());
2043}
2044
2045
ager@chromium.org7c537e22008-10-16 08:43:32 +00002046Address SeqTwoByteString::GetCharsAddress() {
2047 return FIELD_ADDR(this, kHeaderSize);
2048}
2049
2050
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002051uc16* SeqTwoByteString::GetChars() {
2052 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2053}
2054
2055
ager@chromium.org7c537e22008-10-16 08:43:32 +00002056uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057 ASSERT(index >= 0 && index < length());
2058 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2059}
2060
2061
ager@chromium.org7c537e22008-10-16 08:43:32 +00002062void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 ASSERT(index >= 0 && index < length());
2064 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2065}
2066
2067
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002068int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002069 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070}
2071
2072
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002073int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002074 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002075}
2076
2077
ager@chromium.org870a0b62008-11-04 11:43:05 +00002078String* ConsString::first() {
2079 return String::cast(READ_FIELD(this, kFirstOffset));
2080}
2081
2082
2083Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002084 return READ_FIELD(this, kFirstOffset);
2085}
2086
2087
ager@chromium.org870a0b62008-11-04 11:43:05 +00002088void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002090 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091}
2092
2093
ager@chromium.org870a0b62008-11-04 11:43:05 +00002094String* ConsString::second() {
2095 return String::cast(READ_FIELD(this, kSecondOffset));
2096}
2097
2098
2099Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100 return READ_FIELD(this, kSecondOffset);
2101}
2102
2103
ager@chromium.org870a0b62008-11-04 11:43:05 +00002104void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002106 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107}
2108
2109
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2111 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2112}
2113
2114
2115void ExternalAsciiString::set_resource(
2116 ExternalAsciiString::Resource* resource) {
2117 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2118}
2119
2120
2121ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2122 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2123}
2124
2125
2126void ExternalTwoByteString::set_resource(
2127 ExternalTwoByteString::Resource* resource) {
2128 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2129}
2130
2131
ager@chromium.orgac091b72010-05-05 07:34:42 +00002132void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002133 set_finger_index(kEntriesIndex);
2134 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002135}
2136
2137
2138void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002139 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002140 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002141 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002142 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002143 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002144 MakeZeroSize();
2145}
2146
2147
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002148int JSFunctionResultCache::size() {
2149 return Smi::cast(get(kCacheSizeIndex))->value();
2150}
2151
2152
2153void JSFunctionResultCache::set_size(int size) {
2154 set(kCacheSizeIndex, Smi::FromInt(size));
2155}
2156
2157
2158int JSFunctionResultCache::finger_index() {
2159 return Smi::cast(get(kFingerIndex))->value();
2160}
2161
2162
2163void JSFunctionResultCache::set_finger_index(int finger_index) {
2164 set(kFingerIndex, Smi::FromInt(finger_index));
2165}
2166
2167
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002168byte ByteArray::get(int index) {
2169 ASSERT(index >= 0 && index < this->length());
2170 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2171}
2172
2173
2174void ByteArray::set(int index, byte value) {
2175 ASSERT(index >= 0 && index < this->length());
2176 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2177}
2178
2179
2180int ByteArray::get_int(int index) {
2181 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2182 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2183}
2184
2185
2186ByteArray* ByteArray::FromDataStartAddress(Address address) {
2187 ASSERT_TAG_ALIGNED(address);
2188 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2189}
2190
2191
2192Address ByteArray::GetDataStartAddress() {
2193 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2194}
2195
2196
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002197uint8_t* ExternalPixelArray::external_pixel_pointer() {
2198 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002199}
2200
2201
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002202uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002203 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002204 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002205 return ptr[index];
2206}
2207
2208
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002209void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002210 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002211 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002212 ptr[index] = value;
2213}
2214
2215
ager@chromium.org3811b432009-10-28 14:53:37 +00002216void* ExternalArray::external_pointer() {
2217 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2218 return reinterpret_cast<void*>(ptr);
2219}
2220
2221
2222void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2223 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2224 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2225}
2226
2227
2228int8_t ExternalByteArray::get(int index) {
2229 ASSERT((index >= 0) && (index < this->length()));
2230 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2231 return ptr[index];
2232}
2233
2234
2235void ExternalByteArray::set(int index, int8_t value) {
2236 ASSERT((index >= 0) && (index < this->length()));
2237 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2238 ptr[index] = value;
2239}
2240
2241
2242uint8_t ExternalUnsignedByteArray::get(int index) {
2243 ASSERT((index >= 0) && (index < this->length()));
2244 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2245 return ptr[index];
2246}
2247
2248
2249void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2250 ASSERT((index >= 0) && (index < this->length()));
2251 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2252 ptr[index] = value;
2253}
2254
2255
2256int16_t ExternalShortArray::get(int index) {
2257 ASSERT((index >= 0) && (index < this->length()));
2258 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2259 return ptr[index];
2260}
2261
2262
2263void ExternalShortArray::set(int index, int16_t value) {
2264 ASSERT((index >= 0) && (index < this->length()));
2265 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2266 ptr[index] = value;
2267}
2268
2269
2270uint16_t ExternalUnsignedShortArray::get(int index) {
2271 ASSERT((index >= 0) && (index < this->length()));
2272 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2273 return ptr[index];
2274}
2275
2276
2277void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2278 ASSERT((index >= 0) && (index < this->length()));
2279 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2280 ptr[index] = value;
2281}
2282
2283
2284int32_t ExternalIntArray::get(int index) {
2285 ASSERT((index >= 0) && (index < this->length()));
2286 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2287 return ptr[index];
2288}
2289
2290
2291void ExternalIntArray::set(int index, int32_t value) {
2292 ASSERT((index >= 0) && (index < this->length()));
2293 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2294 ptr[index] = value;
2295}
2296
2297
2298uint32_t ExternalUnsignedIntArray::get(int index) {
2299 ASSERT((index >= 0) && (index < this->length()));
2300 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2301 return ptr[index];
2302}
2303
2304
2305void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2306 ASSERT((index >= 0) && (index < this->length()));
2307 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2308 ptr[index] = value;
2309}
2310
2311
2312float ExternalFloatArray::get(int index) {
2313 ASSERT((index >= 0) && (index < this->length()));
2314 float* ptr = static_cast<float*>(external_pointer());
2315 return ptr[index];
2316}
2317
2318
2319void ExternalFloatArray::set(int index, float value) {
2320 ASSERT((index >= 0) && (index < this->length()));
2321 float* ptr = static_cast<float*>(external_pointer());
2322 ptr[index] = value;
2323}
2324
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002325
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002326double ExternalDoubleArray::get(int index) {
2327 ASSERT((index >= 0) && (index < this->length()));
2328 double* ptr = static_cast<double*>(external_pointer());
2329 return ptr[index];
2330}
2331
2332
2333void ExternalDoubleArray::set(int index, double value) {
2334 ASSERT((index >= 0) && (index < this->length()));
2335 double* ptr = static_cast<double*>(external_pointer());
2336 ptr[index] = value;
2337}
2338
2339
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002340int Map::visitor_id() {
2341 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2342}
2343
2344
2345void Map::set_visitor_id(int id) {
2346 ASSERT(0 <= id && id < 256);
2347 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2348}
2349
ager@chromium.org3811b432009-10-28 14:53:37 +00002350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002352 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2353}
2354
2355
2356int Map::inobject_properties() {
2357 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358}
2359
2360
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002361int Map::pre_allocated_property_fields() {
2362 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2363}
2364
2365
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002367 int instance_size = map->instance_size();
2368 if (instance_size != kVariableSizeSentinel) return instance_size;
2369 // We can ignore the "symbol" bit becase it is only set for symbols
2370 // and implies a string type.
2371 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002372 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002374 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002376 if (instance_type == ASCII_STRING_TYPE) {
2377 return SeqAsciiString::SizeFor(
2378 reinterpret_cast<SeqAsciiString*>(this)->length());
2379 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002380 if (instance_type == BYTE_ARRAY_TYPE) {
2381 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2382 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002383 if (instance_type == STRING_TYPE) {
2384 return SeqTwoByteString::SizeFor(
2385 reinterpret_cast<SeqTwoByteString*>(this)->length());
2386 }
2387 ASSERT(instance_type == CODE_TYPE);
2388 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389}
2390
2391
2392void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002393 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002394 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002395 ASSERT(0 <= value && value < 256);
2396 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2397}
2398
2399
ager@chromium.org7c537e22008-10-16 08:43:32 +00002400void Map::set_inobject_properties(int value) {
2401 ASSERT(0 <= value && value < 256);
2402 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2403}
2404
2405
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002406void Map::set_pre_allocated_property_fields(int value) {
2407 ASSERT(0 <= value && value < 256);
2408 WRITE_BYTE_FIELD(this,
2409 kPreAllocatedPropertyFieldsOffset,
2410 static_cast<byte>(value));
2411}
2412
2413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414InstanceType Map::instance_type() {
2415 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2416}
2417
2418
2419void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2421}
2422
2423
2424int Map::unused_property_fields() {
2425 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2426}
2427
2428
2429void Map::set_unused_property_fields(int value) {
2430 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2431}
2432
2433
2434byte Map::bit_field() {
2435 return READ_BYTE_FIELD(this, kBitFieldOffset);
2436}
2437
2438
2439void Map::set_bit_field(byte value) {
2440 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2441}
2442
2443
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002444byte Map::bit_field2() {
2445 return READ_BYTE_FIELD(this, kBitField2Offset);
2446}
2447
2448
2449void Map::set_bit_field2(byte value) {
2450 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2451}
2452
2453
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002454void Map::set_non_instance_prototype(bool value) {
2455 if (value) {
2456 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2457 } else {
2458 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2459 }
2460}
2461
2462
2463bool Map::has_non_instance_prototype() {
2464 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2465}
2466
2467
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002468void Map::set_function_with_prototype(bool value) {
2469 if (value) {
2470 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2471 } else {
2472 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2473 }
2474}
2475
2476
2477bool Map::function_with_prototype() {
2478 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2479}
2480
2481
ager@chromium.org870a0b62008-11-04 11:43:05 +00002482void Map::set_is_access_check_needed(bool access_check_needed) {
2483 if (access_check_needed) {
2484 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2485 } else {
2486 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2487 }
2488}
2489
2490
2491bool Map::is_access_check_needed() {
2492 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2493}
2494
2495
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002496void Map::set_is_extensible(bool value) {
2497 if (value) {
2498 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2499 } else {
2500 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2501 }
2502}
2503
2504bool Map::is_extensible() {
2505 return ((1 << kIsExtensible) & bit_field2()) != 0;
2506}
2507
2508
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002509void Map::set_attached_to_shared_function_info(bool value) {
2510 if (value) {
2511 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2512 } else {
2513 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2514 }
2515}
2516
2517bool Map::attached_to_shared_function_info() {
2518 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2519}
2520
2521
2522void Map::set_is_shared(bool value) {
2523 if (value) {
2524 set_bit_field2(bit_field2() | (1 << kIsShared));
2525 } else {
2526 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2527 }
2528}
2529
2530bool Map::is_shared() {
2531 return ((1 << kIsShared) & bit_field2()) != 0;
2532}
2533
2534
2535JSFunction* Map::unchecked_constructor() {
2536 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2537}
2538
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002539
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002540FixedArray* Map::unchecked_prototype_transitions() {
2541 return reinterpret_cast<FixedArray*>(
2542 READ_FIELD(this, kPrototypeTransitionsOffset));
2543}
2544
2545
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546Code::Flags Code::flags() {
2547 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2548}
2549
2550
2551void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002552 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002553 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002554 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2555 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002556 ExtractArgumentsCountFromFlags(flags) >= 0);
2557 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2558}
2559
2560
2561Code::Kind Code::kind() {
2562 return ExtractKindFromFlags(flags());
2563}
2564
2565
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002566InLoopFlag Code::ic_in_loop() {
2567 return ExtractICInLoopFromFlags(flags());
2568}
2569
2570
kasper.lund7276f142008-07-30 08:49:36 +00002571InlineCacheState Code::ic_state() {
2572 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002573 // Only allow uninitialized or debugger states for non-IC code
2574 // objects. This is used in the debugger to determine whether or not
2575 // a call to code object has been replaced with a debug break call.
2576 ASSERT(is_inline_cache_stub() ||
2577 result == UNINITIALIZED ||
2578 result == DEBUG_BREAK ||
2579 result == DEBUG_PREPARE_STEP_IN);
2580 return result;
2581}
2582
2583
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002584Code::ExtraICState Code::extra_ic_state() {
2585 ASSERT(is_inline_cache_stub());
2586 return ExtractExtraICStateFromFlags(flags());
2587}
2588
2589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002591 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592 return ExtractTypeFromFlags(flags());
2593}
2594
2595
2596int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002597 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002598 return ExtractArgumentsCountFromFlags(flags());
2599}
2600
2601
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002602int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2605 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002606 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002607}
2608
2609
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002610void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002612 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2613 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002614 ASSERT(0 <= major && major < 256);
2615 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002616}
2617
2618
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002619bool Code::optimizable() {
2620 ASSERT(kind() == FUNCTION);
2621 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2622}
2623
2624
2625void Code::set_optimizable(bool value) {
2626 ASSERT(kind() == FUNCTION);
2627 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2628}
2629
2630
2631bool Code::has_deoptimization_support() {
2632 ASSERT(kind() == FUNCTION);
2633 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2634}
2635
2636
2637void Code::set_has_deoptimization_support(bool value) {
2638 ASSERT(kind() == FUNCTION);
2639 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2640}
2641
2642
2643int Code::allow_osr_at_loop_nesting_level() {
2644 ASSERT(kind() == FUNCTION);
2645 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2646}
2647
2648
2649void Code::set_allow_osr_at_loop_nesting_level(int level) {
2650 ASSERT(kind() == FUNCTION);
2651 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2652 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2653}
2654
2655
2656unsigned Code::stack_slots() {
2657 ASSERT(kind() == OPTIMIZED_FUNCTION);
2658 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2659}
2660
2661
2662void Code::set_stack_slots(unsigned slots) {
2663 ASSERT(kind() == OPTIMIZED_FUNCTION);
2664 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2665}
2666
2667
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002668unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002670 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002671}
2672
2673
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002674void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002675 ASSERT(kind() == OPTIMIZED_FUNCTION);
2676 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002677 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678}
2679
2680
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002681unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002682 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002683 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002684}
2685
2686
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002687void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002688 ASSERT(kind() == FUNCTION);
2689 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002690 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691}
2692
2693
2694CheckType Code::check_type() {
2695 ASSERT(is_call_stub() || is_keyed_call_stub());
2696 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2697 return static_cast<CheckType>(type);
2698}
2699
2700
2701void Code::set_check_type(CheckType value) {
2702 ASSERT(is_call_stub() || is_keyed_call_stub());
2703 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2704}
2705
2706
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002707ExternalArrayType Code::external_array_type() {
2708 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2709 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2710 return static_cast<ExternalArrayType>(type);
2711}
2712
2713
2714void Code::set_external_array_type(ExternalArrayType value) {
2715 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2716 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2717}
2718
2719
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002720byte Code::type_recording_binary_op_type() {
2721 ASSERT(is_type_recording_binary_op_stub());
2722 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2723}
2724
2725
2726void Code::set_type_recording_binary_op_type(byte value) {
2727 ASSERT(is_type_recording_binary_op_stub());
2728 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2729}
2730
2731
2732byte Code::type_recording_binary_op_result_type() {
2733 ASSERT(is_type_recording_binary_op_stub());
2734 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2735}
2736
2737
2738void Code::set_type_recording_binary_op_result_type(byte value) {
2739 ASSERT(is_type_recording_binary_op_stub());
2740 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2741}
2742
2743
2744byte Code::compare_state() {
2745 ASSERT(is_compare_ic_stub());
2746 return READ_BYTE_FIELD(this, kCompareStateOffset);
2747}
2748
2749
2750void Code::set_compare_state(byte value) {
2751 ASSERT(is_compare_ic_stub());
2752 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2753}
2754
2755
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002756bool Code::is_inline_cache_stub() {
2757 Kind kind = this->kind();
2758 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2759}
2760
2761
2762Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002763 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002764 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002765 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002767 int argc,
2768 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002769 // Extra IC state is only allowed for monomorphic call IC stubs
2770 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002771 ASSERT(extra_ic_state == kNoExtraICState ||
2772 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002773 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002774 (kind == STORE_IC) ||
2775 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776 // Compute the bit mask.
2777 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002778 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002779 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002780 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002781 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002783 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784 // Cast to flags and validate result before returning it.
2785 Flags result = static_cast<Flags>(bits);
2786 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002787 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002788 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002790 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2792 return result;
2793}
2794
2795
2796Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2797 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002798 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002799 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002800 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002801 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002802 return ComputeFlags(
2803 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002804}
2805
2806
2807Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2808 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2809 return static_cast<Kind>(bits);
2810}
2811
2812
kasper.lund7276f142008-07-30 08:49:36 +00002813InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2814 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 return static_cast<InlineCacheState>(bits);
2816}
2817
2818
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002819Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2820 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2821 return static_cast<ExtraICState>(bits);
2822}
2823
2824
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002825InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2826 int bits = (flags & kFlagsICInLoopMask);
2827 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2828}
2829
2830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2832 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2833 return static_cast<PropertyType>(bits);
2834}
2835
2836
2837int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2838 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2839}
2840
2841
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002842InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2843 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2844 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2845}
2846
2847
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2849 int bits = flags & ~kFlagsTypeMask;
2850 return static_cast<Flags>(bits);
2851}
2852
2853
ager@chromium.org8bb60582008-12-11 12:02:20 +00002854Code* Code::GetCodeFromTargetAddress(Address address) {
2855 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2856 // GetCodeFromTargetAddress might be called when marking objects during mark
2857 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2858 // Code::cast. Code::cast does not work when the object's map is
2859 // marked.
2860 Code* result = reinterpret_cast<Code*>(code);
2861 return result;
2862}
2863
2864
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002865Isolate* Map::isolate() {
2866 return heap()->isolate();
2867}
2868
2869
2870Heap* Map::heap() {
2871 // NOTE: address() helper is not used to save one instruction.
2872 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2873 ASSERT(heap != NULL);
2874 ASSERT(heap->isolate() == Isolate::Current());
2875 return heap;
2876}
2877
2878
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002879Heap* Code::heap() {
2880 // NOTE: address() helper is not used to save one instruction.
2881 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2882 ASSERT(heap != NULL);
2883 ASSERT(heap->isolate() == Isolate::Current());
2884 return heap;
2885}
2886
2887
2888Isolate* Code::isolate() {
2889 return heap()->isolate();
2890}
2891
2892
2893Heap* JSGlobalPropertyCell::heap() {
2894 // NOTE: address() helper is not used to save one instruction.
2895 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2896 ASSERT(heap != NULL);
2897 ASSERT(heap->isolate() == Isolate::Current());
2898 return heap;
2899}
2900
2901
2902Isolate* JSGlobalPropertyCell::isolate() {
2903 return heap()->isolate();
2904}
2905
2906
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002907Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2908 return HeapObject::
2909 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2910}
2911
2912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913Object* Map::prototype() {
2914 return READ_FIELD(this, kPrototypeOffset);
2915}
2916
2917
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002918void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002919 ASSERT(value->IsNull() || value->IsJSObject());
2920 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002921 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002922}
2923
2924
lrn@chromium.org303ada72010-10-27 09:33:13 +00002925MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002926 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002927 Object* obj;
2928 { MaybeObject* maybe_obj = CopyDropTransitions();
2929 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2930 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002931 Map* new_map = Map::cast(obj);
2932 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002933 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002934 return new_map;
2935}
2936
2937
lrn@chromium.org303ada72010-10-27 09:33:13 +00002938MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002939 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002940 Object* obj;
2941 { MaybeObject* maybe_obj = CopyDropTransitions();
2942 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2943 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002944 Map* new_map = Map::cast(obj);
2945 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002946 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002947 return new_map;
2948}
2949
2950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951ACCESSORS(Map, instance_descriptors, DescriptorArray,
2952 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002953ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002954ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002955ACCESSORS(Map, constructor, Object, kConstructorOffset)
2956
2957ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2958ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002959ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
2960 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002961
2962ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2963ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002964ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002965
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002966ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967
2968ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2969ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2970ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2971ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2972ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2973
2974ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2975ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2976ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2977
2978ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2979ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2980ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2981ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2982ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2983ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2984
2985ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2986ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2987
2988ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2989ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2990
2991ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2992ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002993ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2994 kPropertyAccessorsOffset)
2995ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2996 kPrototypeTemplateOffset)
2997ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2998ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2999 kNamedPropertyHandlerOffset)
3000ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3001 kIndexedPropertyHandlerOffset)
3002ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3003 kInstanceTemplateOffset)
3004ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3005ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3007 kInstanceCallHandlerOffset)
3008ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3009 kAccessCheckInfoOffset)
3010ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3011
3012ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003013ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3014 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003015
3016ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3017ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3018
3019ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3020
3021ACCESSORS(Script, source, Object, kSourceOffset)
3022ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003023ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003024ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3025ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003026ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003027ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003028ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
3029ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003030ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003031ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003032ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003033ACCESSORS(Script, eval_from_instructions_offset, Smi,
3034 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003036#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003037ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3038ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3039ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3040ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3041
3042ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3043ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3044ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3045ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003046#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003047
3048ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003049ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3050ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003051ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3052 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003053ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003054ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3055ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003056ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003057ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3058 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059
3060BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3061 kHiddenPrototypeBit)
3062BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3063BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3064 kNeedsAccessCheckBit)
3065BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3066 kIsExpressionBit)
3067BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3068 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003069BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003070 has_only_simple_this_property_assignments,
3071 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003072BOOL_ACCESSORS(SharedFunctionInfo,
3073 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003074 allows_lazy_compilation,
3075 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003076
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003077
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003078#if V8_HOST_ARCH_32_BIT
3079SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3080SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003082SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003083 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003084SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3085SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003087SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3088SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003089 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003090SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003091 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003092SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003093 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003095#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003097#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003098 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003099 int holder::name() { \
3100 int value = READ_INT_FIELD(this, offset); \
3101 ASSERT(kHeapObjectTag == 1); \
3102 ASSERT((value & kHeapObjectTag) == 0); \
3103 return value >> 1; \
3104 } \
3105 void holder::set_##name(int value) { \
3106 ASSERT(kHeapObjectTag == 1); \
3107 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3108 (value & 0xC0000000) == 0x000000000); \
3109 WRITE_INT_FIELD(this, \
3110 offset, \
3111 (value << 1) & ~kHeapObjectTag); \
3112 }
3113
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003114#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3115 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003116 INT_ACCESSORS(holder, name, offset)
3117
3118
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003119PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003120PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3121 formal_parameter_count,
3122 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003123
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003124PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3125 expected_nof_properties,
3126 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003127PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3128
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003129PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3130PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3131 start_position_and_type,
3132 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003133
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003134PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3135 function_token_position,
3136 kFunctionTokenPositionOffset)
3137PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3138 compiler_hints,
3139 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003140
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003141PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3142 this_property_assignments_count,
3143 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003145#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003146
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003147
3148int SharedFunctionInfo::construction_count() {
3149 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3150}
3151
3152
3153void SharedFunctionInfo::set_construction_count(int value) {
3154 ASSERT(0 <= value && value < 256);
3155 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3156}
3157
3158
3159bool SharedFunctionInfo::live_objects_may_exist() {
3160 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3161}
3162
3163
3164void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3165 if (value) {
3166 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3167 } else {
3168 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3169 }
3170}
3171
3172
3173bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003174 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003175}
3176
3177
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178bool SharedFunctionInfo::optimization_disabled() {
3179 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3180}
3181
3182
3183void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3184 set_compiler_hints(BooleanBit::set(compiler_hints(),
3185 kOptimizationDisabled,
3186 disable));
3187 // If disabling optimizations we reflect that in the code object so
3188 // it will not be counted as optimizable code.
3189 if ((code()->kind() == Code::FUNCTION) && disable) {
3190 code()->set_optimizable(false);
3191 }
3192}
3193
3194
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003195bool SharedFunctionInfo::strict_mode() {
3196 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3197}
3198
3199
3200void SharedFunctionInfo::set_strict_mode(bool value) {
3201 set_compiler_hints(BooleanBit::set(compiler_hints(),
3202 kStrictModeFunction,
3203 value));
3204}
3205
3206
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003207ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3208ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3209
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003210bool Script::HasValidSource() {
3211 Object* src = this->source();
3212 if (!src->IsString()) return true;
3213 String* src_str = String::cast(src);
3214 if (!StringShape(src_str).IsExternal()) return true;
3215 if (src_str->IsAsciiRepresentation()) {
3216 return ExternalAsciiString::cast(src)->resource() != NULL;
3217 } else if (src_str->IsTwoByteRepresentation()) {
3218 return ExternalTwoByteString::cast(src)->resource() != NULL;
3219 }
3220 return true;
3221}
3222
3223
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003224void SharedFunctionInfo::DontAdaptArguments() {
3225 ASSERT(code()->kind() == Code::BUILTIN);
3226 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3227}
3228
3229
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003230int SharedFunctionInfo::start_position() {
3231 return start_position_and_type() >> kStartPositionShift;
3232}
3233
3234
3235void SharedFunctionInfo::set_start_position(int start_position) {
3236 set_start_position_and_type((start_position << kStartPositionShift)
3237 | (start_position_and_type() & ~kStartPositionMask));
3238}
3239
3240
3241Code* SharedFunctionInfo::code() {
3242 return Code::cast(READ_FIELD(this, kCodeOffset));
3243}
3244
3245
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003246Code* SharedFunctionInfo::unchecked_code() {
3247 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3248}
3249
3250
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003251void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003253 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
ager@chromium.orgb5737492010-07-15 09:29:43 +00003257SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3258 return reinterpret_cast<SerializedScopeInfo*>(
3259 READ_FIELD(this, kScopeInfoOffset));
3260}
3261
3262
3263void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3264 WriteBarrierMode mode) {
3265 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003266 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003267}
3268
3269
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003270Smi* SharedFunctionInfo::deopt_counter() {
3271 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3272}
3273
3274
3275void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3276 WRITE_FIELD(this, kDeoptCounterOffset, value);
3277}
3278
3279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003281 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003282 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283}
3284
3285
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003286bool SharedFunctionInfo::IsApiFunction() {
3287 return function_data()->IsFunctionTemplateInfo();
3288}
3289
3290
3291FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3292 ASSERT(IsApiFunction());
3293 return FunctionTemplateInfo::cast(function_data());
3294}
3295
3296
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003297bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003298 return function_data()->IsSmi();
3299}
3300
3301
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003302BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3303 ASSERT(HasBuiltinFunctionId());
3304 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003305}
3306
3307
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003308int SharedFunctionInfo::code_age() {
3309 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3310}
3311
3312
3313void SharedFunctionInfo::set_code_age(int code_age) {
3314 set_compiler_hints(compiler_hints() |
3315 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3316}
3317
3318
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319bool SharedFunctionInfo::has_deoptimization_support() {
3320 Code* code = this->code();
3321 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3322}
3323
3324
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003325bool JSFunction::IsBuiltin() {
3326 return context()->global()->IsJSBuiltinsObject();
3327}
3328
3329
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003330bool JSFunction::NeedsArgumentsAdaption() {
3331 return shared()->formal_parameter_count() !=
3332 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3333}
3334
3335
3336bool JSFunction::IsOptimized() {
3337 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3338}
3339
3340
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003341bool JSFunction::IsOptimizable() {
3342 return code()->kind() == Code::FUNCTION && code()->optimizable();
3343}
3344
3345
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003346bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003347 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003348}
3349
3350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003352 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003353}
3354
3355
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003356Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003357 return reinterpret_cast<Code*>(
3358 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003359}
3360
3361
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003362void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003363 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003364 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003365 Address entry = value->entry();
3366 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367}
3368
3369
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370void JSFunction::ReplaceCode(Code* code) {
3371 bool was_optimized = IsOptimized();
3372 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3373
3374 set_code(code);
3375
3376 // Add/remove the function from the list of optimized functions for this
3377 // context based on the state change.
3378 if (!was_optimized && is_optimized) {
3379 context()->global_context()->AddOptimizedFunction(this);
3380 }
3381 if (was_optimized && !is_optimized) {
3382 context()->global_context()->RemoveOptimizedFunction(this);
3383 }
3384}
3385
3386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003387Context* JSFunction::context() {
3388 return Context::cast(READ_FIELD(this, kContextOffset));
3389}
3390
3391
3392Object* JSFunction::unchecked_context() {
3393 return READ_FIELD(this, kContextOffset);
3394}
3395
3396
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003397SharedFunctionInfo* JSFunction::unchecked_shared() {
3398 return reinterpret_cast<SharedFunctionInfo*>(
3399 READ_FIELD(this, kSharedFunctionInfoOffset));
3400}
3401
3402
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003403void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003404 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405 WRITE_FIELD(this, kContextOffset, value);
3406 WRITE_BARRIER(this, kContextOffset);
3407}
3408
3409ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3410 kPrototypeOrInitialMapOffset)
3411
3412
3413Map* JSFunction::initial_map() {
3414 return Map::cast(prototype_or_initial_map());
3415}
3416
3417
3418void JSFunction::set_initial_map(Map* value) {
3419 set_prototype_or_initial_map(value);
3420}
3421
3422
3423bool JSFunction::has_initial_map() {
3424 return prototype_or_initial_map()->IsMap();
3425}
3426
3427
3428bool JSFunction::has_instance_prototype() {
3429 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3430}
3431
3432
3433bool JSFunction::has_prototype() {
3434 return map()->has_non_instance_prototype() || has_instance_prototype();
3435}
3436
3437
3438Object* JSFunction::instance_prototype() {
3439 ASSERT(has_instance_prototype());
3440 if (has_initial_map()) return initial_map()->prototype();
3441 // When there is no initial map and the prototype is a JSObject, the
3442 // initial map field is used for the prototype field.
3443 return prototype_or_initial_map();
3444}
3445
3446
3447Object* JSFunction::prototype() {
3448 ASSERT(has_prototype());
3449 // If the function's prototype property has been set to a non-JSObject
3450 // value, that value is stored in the constructor field of the map.
3451 if (map()->has_non_instance_prototype()) return map()->constructor();
3452 return instance_prototype();
3453}
3454
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003455bool JSFunction::should_have_prototype() {
3456 return map()->function_with_prototype();
3457}
3458
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003459
3460bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003461 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462}
3463
3464
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003465int JSFunction::NumberOfLiterals() {
3466 return literals()->length();
3467}
3468
3469
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003471 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003472 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003473}
3474
3475
3476void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3477 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003478 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003479 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3480 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3481}
3482
3483
3484Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003485 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003486 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3487}
3488
3489
3490void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3491 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003492 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003493 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003494 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003495}
3496
3497
3498Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003499 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500}
3501
3502
3503void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003504 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505}
3506
3507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508ACCESSORS(JSValue, value, Object, kValueOffset)
3509
3510
3511JSValue* JSValue::cast(Object* obj) {
3512 ASSERT(obj->IsJSValue());
3513 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3514 return reinterpret_cast<JSValue*>(obj);
3515}
3516
3517
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003518ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3519ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3520ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3521ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3522ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3523SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3524SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3525
3526
3527JSMessageObject* JSMessageObject::cast(Object* obj) {
3528 ASSERT(obj->IsJSMessageObject());
3529 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3530 return reinterpret_cast<JSMessageObject*>(obj);
3531}
3532
3533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003535ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003536ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003537
3538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003539byte* Code::instruction_start() {
3540 return FIELD_ADDR(this, kHeaderSize);
3541}
3542
3543
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003544byte* Code::instruction_end() {
3545 return instruction_start() + instruction_size();
3546}
3547
3548
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003549int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003550 return RoundUp(instruction_size(), kObjectAlignment);
3551}
3552
3553
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003554FixedArray* Code::unchecked_deoptimization_data() {
3555 return reinterpret_cast<FixedArray*>(
3556 READ_FIELD(this, kDeoptimizationDataOffset));
3557}
3558
3559
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003560ByteArray* Code::unchecked_relocation_info() {
3561 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003562}
3563
3564
3565byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003566 return unchecked_relocation_info()->GetDataStartAddress();
3567}
3568
3569
3570int Code::relocation_size() {
3571 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003572}
3573
3574
3575byte* Code::entry() {
3576 return instruction_start();
3577}
3578
3579
3580bool Code::contains(byte* pc) {
3581 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003582 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003583}
3584
3585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003586ACCESSORS(JSArray, length, Object, kLengthOffset)
3587
3588
ager@chromium.org236ad962008-09-25 09:45:57 +00003589ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003590
3591
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003592JSRegExp::Type JSRegExp::TypeTag() {
3593 Object* data = this->data();
3594 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3595 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3596 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003597}
3598
3599
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003600int JSRegExp::CaptureCount() {
3601 switch (TypeTag()) {
3602 case ATOM:
3603 return 0;
3604 case IRREGEXP:
3605 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3606 default:
3607 UNREACHABLE();
3608 return -1;
3609 }
3610}
3611
3612
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003613JSRegExp::Flags JSRegExp::GetFlags() {
3614 ASSERT(this->data()->IsFixedArray());
3615 Object* data = this->data();
3616 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3617 return Flags(smi->value());
3618}
3619
3620
3621String* JSRegExp::Pattern() {
3622 ASSERT(this->data()->IsFixedArray());
3623 Object* data = this->data();
3624 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3625 return pattern;
3626}
3627
3628
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003629Object* JSRegExp::DataAt(int index) {
3630 ASSERT(TypeTag() != NOT_COMPILED);
3631 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003632}
3633
3634
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003635void JSRegExp::SetDataAt(int index, Object* value) {
3636 ASSERT(TypeTag() != NOT_COMPILED);
3637 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3638 FixedArray::cast(data())->set(index, value);
3639}
3640
3641
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003642JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003643 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003644 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3645 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003646 return FAST_ELEMENTS;
3647 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003648 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003649 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003650 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3651 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003652 ASSERT(array->IsDictionary());
3653 return DICTIONARY_ELEMENTS;
3654 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003655 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003656 if (array->IsExternalArray()) {
3657 switch (array->map()->instance_type()) {
3658 case EXTERNAL_BYTE_ARRAY_TYPE:
3659 return EXTERNAL_BYTE_ELEMENTS;
3660 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3661 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3662 case EXTERNAL_SHORT_ARRAY_TYPE:
3663 return EXTERNAL_SHORT_ELEMENTS;
3664 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3665 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3666 case EXTERNAL_INT_ARRAY_TYPE:
3667 return EXTERNAL_INT_ELEMENTS;
3668 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3669 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003670 case EXTERNAL_FLOAT_ARRAY_TYPE:
3671 return EXTERNAL_FLOAT_ELEMENTS;
3672 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3673 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003674 case EXTERNAL_PIXEL_ARRAY_TYPE:
3675 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003676 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003677 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003678 }
3679 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003680 UNREACHABLE();
3681 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003682}
3683
3684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003686 return GetElementsKind() == FAST_ELEMENTS;
3687}
3688
3689
3690bool JSObject::HasDictionaryElements() {
3691 return GetElementsKind() == DICTIONARY_ELEMENTS;
3692}
3693
3694
ager@chromium.org3811b432009-10-28 14:53:37 +00003695bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003696 HeapObject* array = elements();
3697 ASSERT(array != NULL);
3698 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003699}
3700
3701
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003702#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3703bool JSObject::HasExternal##name##Elements() { \
3704 HeapObject* array = elements(); \
3705 ASSERT(array != NULL); \
3706 if (!array->IsHeapObject()) \
3707 return false; \
3708 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003709}
3710
3711
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003712EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3713EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3714EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3715EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3716 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3717EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3718EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3719 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3720EXTERNAL_ELEMENTS_CHECK(Float,
3721 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003722EXTERNAL_ELEMENTS_CHECK(Double,
3723 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003724EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003725
3726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727bool JSObject::HasNamedInterceptor() {
3728 return map()->has_named_interceptor();
3729}
3730
3731
3732bool JSObject::HasIndexedInterceptor() {
3733 return map()->has_indexed_interceptor();
3734}
3735
3736
ager@chromium.org5c838252010-02-19 08:53:10 +00003737bool JSObject::AllowsSetElementsLength() {
3738 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003739 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003740 return result;
3741}
3742
3743
lrn@chromium.org303ada72010-10-27 09:33:13 +00003744MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003745 ASSERT(HasFastElements());
3746 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003747 Isolate* isolate = GetIsolate();
3748 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003749 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003750 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3751 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003752 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3753 return maybe_writable_elems;
3754 }
3755 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003756 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003757 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003758 return writable_elems;
3759}
3760
3761
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003762StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003764 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765}
3766
3767
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003768NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003769 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003770 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003771}
3772
3773
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003774bool String::IsHashFieldComputed(uint32_t field) {
3775 return (field & kHashNotComputedMask) == 0;
3776}
3777
3778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003779bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003780 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003781}
3782
3783
3784uint32_t String::Hash() {
3785 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003786 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003787 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003788 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003789 return ComputeAndSetHash();
3790}
3791
3792
ager@chromium.org7c537e22008-10-16 08:43:32 +00003793StringHasher::StringHasher(int length)
3794 : length_(length),
3795 raw_running_hash_(0),
3796 array_index_(0),
3797 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3798 is_first_char_(true),
3799 is_valid_(true) { }
3800
3801
3802bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003803 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003804}
3805
3806
3807void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003808 // Use the Jenkins one-at-a-time hash function to update the hash
3809 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003810 raw_running_hash_ += c;
3811 raw_running_hash_ += (raw_running_hash_ << 10);
3812 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003813 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003814 if (is_array_index_) {
3815 if (c < '0' || c > '9') {
3816 is_array_index_ = false;
3817 } else {
3818 int d = c - '0';
3819 if (is_first_char_) {
3820 is_first_char_ = false;
3821 if (c == '0' && length_ > 1) {
3822 is_array_index_ = false;
3823 return;
3824 }
3825 }
3826 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3827 is_array_index_ = false;
3828 } else {
3829 array_index_ = array_index_ * 10 + d;
3830 }
3831 }
3832 }
3833}
3834
3835
3836void StringHasher::AddCharacterNoIndex(uc32 c) {
3837 ASSERT(!is_array_index());
3838 raw_running_hash_ += c;
3839 raw_running_hash_ += (raw_running_hash_ << 10);
3840 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3841}
3842
3843
3844uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003845 // Get the calculated raw hash value and do some more bit ops to distribute
3846 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003847 uint32_t result = raw_running_hash_;
3848 result += (result << 3);
3849 result ^= (result >> 11);
3850 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003851 if (result == 0) {
3852 result = 27;
3853 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003854 return result;
3855}
3856
3857
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003858template <typename schar>
3859uint32_t HashSequentialString(const schar* chars, int length) {
3860 StringHasher hasher(length);
3861 if (!hasher.has_trivial_hash()) {
3862 int i;
3863 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3864 hasher.AddCharacter(chars[i]);
3865 }
3866 for (; i < length; i++) {
3867 hasher.AddCharacterNoIndex(chars[i]);
3868 }
3869 }
3870 return hasher.GetHashField();
3871}
3872
3873
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003874bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003875 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003876 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3877 return false;
3878 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879 return SlowAsArrayIndex(index);
3880}
3881
3882
3883Object* JSObject::GetPrototype() {
3884 return JSObject::cast(this)->map()->prototype();
3885}
3886
3887
3888PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3889 return GetPropertyAttributeWithReceiver(this, key);
3890}
3891
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003892// TODO(504): this may be useful in other places too where JSGlobalProxy
3893// is used.
3894Object* JSObject::BypassGlobalProxy() {
3895 if (IsJSGlobalProxy()) {
3896 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003897 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003898 ASSERT(proto->IsJSGlobalObject());
3899 return proto;
3900 }
3901 return this;
3902}
3903
3904
3905bool JSObject::HasHiddenPropertiesObject() {
3906 ASSERT(!IsJSGlobalProxy());
3907 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003908 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003909 false) != ABSENT;
3910}
3911
3912
3913Object* JSObject::GetHiddenPropertiesObject() {
3914 ASSERT(!IsJSGlobalProxy());
3915 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003916 // You can't install a getter on a property indexed by the hidden symbol,
3917 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3918 // object.
3919 Object* result =
3920 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003921 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00003922 &attributes)->ToObjectUnchecked();
3923 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003924}
3925
3926
lrn@chromium.org303ada72010-10-27 09:33:13 +00003927MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003928 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003929 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003930 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003931 DONT_ENUM,
3932 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003933}
3934
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935
3936bool JSObject::HasElement(uint32_t index) {
3937 return HasElementWithReceiver(this, index);
3938}
3939
3940
3941bool AccessorInfo::all_can_read() {
3942 return BooleanBit::get(flag(), kAllCanReadBit);
3943}
3944
3945
3946void AccessorInfo::set_all_can_read(bool value) {
3947 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3948}
3949
3950
3951bool AccessorInfo::all_can_write() {
3952 return BooleanBit::get(flag(), kAllCanWriteBit);
3953}
3954
3955
3956void AccessorInfo::set_all_can_write(bool value) {
3957 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3958}
3959
3960
ager@chromium.org870a0b62008-11-04 11:43:05 +00003961bool AccessorInfo::prohibits_overwriting() {
3962 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3963}
3964
3965
3966void AccessorInfo::set_prohibits_overwriting(bool value) {
3967 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3968}
3969
3970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971PropertyAttributes AccessorInfo::property_attributes() {
3972 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3973}
3974
3975
3976void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3977 ASSERT(AttributesField::is_valid(attributes));
3978 int rest_value = flag()->value() & ~AttributesField::mask();
3979 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3980}
3981
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003982
3983template<typename Shape, typename Key>
3984void Dictionary<Shape, Key>::SetEntry(int entry,
3985 Object* key,
3986 Object* value) {
3987 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
3988}
3989
3990
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003991template<typename Shape, typename Key>
3992void Dictionary<Shape, Key>::SetEntry(int entry,
3993 Object* key,
3994 Object* value,
3995 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003996 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003997 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003998 AssertNoAllocation no_gc;
3999 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004000 FixedArray::set(index, key, mode);
4001 FixedArray::set(index+1, value, mode);
4002 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004003}
4004
4005
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004006bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4007 ASSERT(other->IsNumber());
4008 return key == static_cast<uint32_t>(other->Number());
4009}
4010
4011
4012uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4013 return ComputeIntegerHash(key);
4014}
4015
4016
4017uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4018 ASSERT(other->IsNumber());
4019 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4020}
4021
4022
4023MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4024 return Isolate::Current()->heap()->NumberFromUint32(key);
4025}
4026
4027
4028bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4029 // We know that all entries in a hash table had their hash keys created.
4030 // Use that knowledge to have fast failure.
4031 if (key->Hash() != String::cast(other)->Hash()) return false;
4032 return key->Equals(String::cast(other));
4033}
4034
4035
4036uint32_t StringDictionaryShape::Hash(String* key) {
4037 return key->Hash();
4038}
4039
4040
4041uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4042 return String::cast(other)->Hash();
4043}
4044
4045
4046MaybeObject* StringDictionaryShape::AsObject(String* key) {
4047 return key;
4048}
4049
4050
4051void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004052 // No write barrier is needed since empty_fixed_array is not in new space.
4053 // Please note this function is used during marking:
4054 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004055 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4056 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004057}
4058
4059
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004060void JSArray::EnsureSize(int required_size) {
4061 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004062 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004063 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4064 if (elts->length() < required_size) {
4065 // Doubling in size would be overkill, but leave some slack to avoid
4066 // constantly growing.
4067 Expand(required_size + (required_size >> 3));
4068 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004069 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004070 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4071 // Expand will allocate a new backing store in new space even if the size
4072 // we asked for isn't larger than what we had before.
4073 Expand(required_size);
4074 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004075}
4076
4077
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004078void JSArray::set_length(Smi* length) {
4079 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4080}
4081
4082
ager@chromium.org7c537e22008-10-16 08:43:32 +00004083void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004084 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004085 set_elements(storage);
4086}
4087
4088
lrn@chromium.org303ada72010-10-27 09:33:13 +00004089MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004090 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004091 return GetHeap()->CopyFixedArray(this);
4092}
4093
4094
4095Relocatable::Relocatable(Isolate* isolate) {
4096 ASSERT(isolate == Isolate::Current());
4097 isolate_ = isolate;
4098 prev_ = isolate->relocatable_top();
4099 isolate->set_relocatable_top(this);
4100}
4101
4102
4103Relocatable::~Relocatable() {
4104 ASSERT(isolate_ == Isolate::Current());
4105 ASSERT_EQ(isolate_->relocatable_top(), this);
4106 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004107}
4108
4109
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004110int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4111 return map->instance_size();
4112}
4113
4114
4115void Proxy::ProxyIterateBody(ObjectVisitor* v) {
4116 v->VisitExternalReference(
4117 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4118}
4119
4120
4121template<typename StaticVisitor>
4122void Proxy::ProxyIterateBody() {
4123 StaticVisitor::VisitExternalReference(
4124 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4125}
4126
4127
4128void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4129 typedef v8::String::ExternalAsciiStringResource Resource;
4130 v->VisitExternalAsciiString(
4131 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4132}
4133
4134
4135template<typename StaticVisitor>
4136void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4137 typedef v8::String::ExternalAsciiStringResource Resource;
4138 StaticVisitor::VisitExternalAsciiString(
4139 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4140}
4141
4142
4143void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4144 typedef v8::String::ExternalStringResource Resource;
4145 v->VisitExternalTwoByteString(
4146 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4147}
4148
4149
4150template<typename StaticVisitor>
4151void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4152 typedef v8::String::ExternalStringResource Resource;
4153 StaticVisitor::VisitExternalTwoByteString(
4154 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4155}
4156
4157#define SLOT_ADDR(obj, offset) \
4158 reinterpret_cast<Object**>((obj)->address() + offset)
4159
4160template<int start_offset, int end_offset, int size>
4161void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4162 HeapObject* obj,
4163 ObjectVisitor* v) {
4164 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4165}
4166
4167
4168template<int start_offset>
4169void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4170 int object_size,
4171 ObjectVisitor* v) {
4172 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4173}
4174
4175#undef SLOT_ADDR
4176
4177
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004178#undef CAST_ACCESSOR
4179#undef INT_ACCESSORS
4180#undef SMI_ACCESSORS
4181#undef ACCESSORS
4182#undef FIELD_ADDR
4183#undef READ_FIELD
4184#undef WRITE_FIELD
4185#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004186#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004187#undef READ_MEMADDR_FIELD
4188#undef WRITE_MEMADDR_FIELD
4189#undef READ_DOUBLE_FIELD
4190#undef WRITE_DOUBLE_FIELD
4191#undef READ_INT_FIELD
4192#undef WRITE_INT_FIELD
4193#undef READ_SHORT_FIELD
4194#undef WRITE_SHORT_FIELD
4195#undef READ_BYTE_FIELD
4196#undef WRITE_BYTE_FIELD
4197
4198
4199} } // namespace v8::internal
4200
4201#endif // V8_OBJECTS_INL_H_