blob: e3d21cc658ea6d2445c22ebab33fedc3033bb969 [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 ||
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002612 kind() == TYPE_RECORDING_UNARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2614 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002615 ASSERT(0 <= major && major < 256);
2616 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002617}
2618
2619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620bool Code::optimizable() {
2621 ASSERT(kind() == FUNCTION);
2622 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2623}
2624
2625
2626void Code::set_optimizable(bool value) {
2627 ASSERT(kind() == FUNCTION);
2628 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2629}
2630
2631
2632bool Code::has_deoptimization_support() {
2633 ASSERT(kind() == FUNCTION);
2634 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2635}
2636
2637
2638void Code::set_has_deoptimization_support(bool value) {
2639 ASSERT(kind() == FUNCTION);
2640 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2641}
2642
2643
2644int Code::allow_osr_at_loop_nesting_level() {
2645 ASSERT(kind() == FUNCTION);
2646 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2647}
2648
2649
2650void Code::set_allow_osr_at_loop_nesting_level(int level) {
2651 ASSERT(kind() == FUNCTION);
2652 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2653 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2654}
2655
2656
2657unsigned Code::stack_slots() {
2658 ASSERT(kind() == OPTIMIZED_FUNCTION);
2659 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2660}
2661
2662
2663void Code::set_stack_slots(unsigned slots) {
2664 ASSERT(kind() == OPTIMIZED_FUNCTION);
2665 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2666}
2667
2668
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002669unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002670 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002671 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002672}
2673
2674
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002675void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676 ASSERT(kind() == OPTIMIZED_FUNCTION);
2677 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002678 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679}
2680
2681
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002682unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002683 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002684 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002685}
2686
2687
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002688void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689 ASSERT(kind() == FUNCTION);
2690 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002691 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002692}
2693
2694
2695CheckType Code::check_type() {
2696 ASSERT(is_call_stub() || is_keyed_call_stub());
2697 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2698 return static_cast<CheckType>(type);
2699}
2700
2701
2702void Code::set_check_type(CheckType value) {
2703 ASSERT(is_call_stub() || is_keyed_call_stub());
2704 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2705}
2706
2707
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002708ExternalArrayType Code::external_array_type() {
2709 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2710 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2711 return static_cast<ExternalArrayType>(type);
2712}
2713
2714
2715void Code::set_external_array_type(ExternalArrayType value) {
2716 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2717 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2718}
2719
2720
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002721byte Code::type_recording_unary_op_type() {
2722 ASSERT(is_type_recording_unary_op_stub());
2723 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2724}
2725
2726
2727void Code::set_type_recording_unary_op_type(byte value) {
2728 ASSERT(is_type_recording_unary_op_stub());
2729 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2730}
2731
2732
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002733byte Code::type_recording_binary_op_type() {
2734 ASSERT(is_type_recording_binary_op_stub());
2735 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2736}
2737
2738
2739void Code::set_type_recording_binary_op_type(byte value) {
2740 ASSERT(is_type_recording_binary_op_stub());
2741 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2742}
2743
2744
2745byte Code::type_recording_binary_op_result_type() {
2746 ASSERT(is_type_recording_binary_op_stub());
2747 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2748}
2749
2750
2751void Code::set_type_recording_binary_op_result_type(byte value) {
2752 ASSERT(is_type_recording_binary_op_stub());
2753 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2754}
2755
2756
2757byte Code::compare_state() {
2758 ASSERT(is_compare_ic_stub());
2759 return READ_BYTE_FIELD(this, kCompareStateOffset);
2760}
2761
2762
2763void Code::set_compare_state(byte value) {
2764 ASSERT(is_compare_ic_stub());
2765 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2766}
2767
2768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002769bool Code::is_inline_cache_stub() {
2770 Kind kind = this->kind();
2771 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2772}
2773
2774
2775Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002776 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002777 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002778 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002780 int argc,
2781 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002782 // Extra IC state is only allowed for monomorphic call IC stubs
2783 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002784 ASSERT(extra_ic_state == kNoExtraICState ||
2785 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002786 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002787 (kind == STORE_IC) ||
2788 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789 // Compute the bit mask.
2790 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002791 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002792 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002793 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002794 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002796 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002797 // Cast to flags and validate result before returning it.
2798 Flags result = static_cast<Flags>(bits);
2799 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002800 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002801 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002803 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002804 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2805 return result;
2806}
2807
2808
2809Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2810 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002811 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002812 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002813 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002815 return ComputeFlags(
2816 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002817}
2818
2819
2820Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2821 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2822 return static_cast<Kind>(bits);
2823}
2824
2825
kasper.lund7276f142008-07-30 08:49:36 +00002826InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2827 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002828 return static_cast<InlineCacheState>(bits);
2829}
2830
2831
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002832Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2833 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2834 return static_cast<ExtraICState>(bits);
2835}
2836
2837
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002838InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2839 int bits = (flags & kFlagsICInLoopMask);
2840 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2841}
2842
2843
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002844PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2845 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2846 return static_cast<PropertyType>(bits);
2847}
2848
2849
2850int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2851 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2852}
2853
2854
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002855InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2856 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2857 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2858}
2859
2860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002861Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2862 int bits = flags & ~kFlagsTypeMask;
2863 return static_cast<Flags>(bits);
2864}
2865
2866
ager@chromium.org8bb60582008-12-11 12:02:20 +00002867Code* Code::GetCodeFromTargetAddress(Address address) {
2868 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2869 // GetCodeFromTargetAddress might be called when marking objects during mark
2870 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2871 // Code::cast. Code::cast does not work when the object's map is
2872 // marked.
2873 Code* result = reinterpret_cast<Code*>(code);
2874 return result;
2875}
2876
2877
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002878Isolate* Map::isolate() {
2879 return heap()->isolate();
2880}
2881
2882
2883Heap* Map::heap() {
2884 // NOTE: address() helper is not used to save one instruction.
2885 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2886 ASSERT(heap != NULL);
2887 ASSERT(heap->isolate() == Isolate::Current());
2888 return heap;
2889}
2890
2891
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002892Heap* Code::heap() {
2893 // NOTE: address() helper is not used to save one instruction.
2894 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2895 ASSERT(heap != NULL);
2896 ASSERT(heap->isolate() == Isolate::Current());
2897 return heap;
2898}
2899
2900
2901Isolate* Code::isolate() {
2902 return heap()->isolate();
2903}
2904
2905
2906Heap* JSGlobalPropertyCell::heap() {
2907 // NOTE: address() helper is not used to save one instruction.
2908 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2909 ASSERT(heap != NULL);
2910 ASSERT(heap->isolate() == Isolate::Current());
2911 return heap;
2912}
2913
2914
2915Isolate* JSGlobalPropertyCell::isolate() {
2916 return heap()->isolate();
2917}
2918
2919
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002920Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2921 return HeapObject::
2922 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2923}
2924
2925
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926Object* Map::prototype() {
2927 return READ_FIELD(this, kPrototypeOffset);
2928}
2929
2930
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002931void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932 ASSERT(value->IsNull() || value->IsJSObject());
2933 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002934 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002935}
2936
2937
lrn@chromium.org303ada72010-10-27 09:33:13 +00002938MaybeObject* Map::GetFastElementsMap() {
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(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002946 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002947 return new_map;
2948}
2949
2950
lrn@chromium.org303ada72010-10-27 09:33:13 +00002951MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002952 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002953 Object* obj;
2954 { MaybeObject* maybe_obj = CopyDropTransitions();
2955 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2956 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002957 Map* new_map = Map::cast(obj);
2958 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002959 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002960 return new_map;
2961}
2962
2963
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964ACCESSORS(Map, instance_descriptors, DescriptorArray,
2965 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002966ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002967ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968ACCESSORS(Map, constructor, Object, kConstructorOffset)
2969
2970ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2971ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002972ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
2973 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002974
2975ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2976ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002977ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002979ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002980
2981ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2982ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2983ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2984ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2985ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2986
2987ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2988ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2989ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2990
2991ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2992ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2993ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2994ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2995ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2996ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2997
2998ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2999ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3000
3001ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3002ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3003
3004ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3005ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3007 kPropertyAccessorsOffset)
3008ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3009 kPrototypeTemplateOffset)
3010ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3011ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3012 kNamedPropertyHandlerOffset)
3013ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3014 kIndexedPropertyHandlerOffset)
3015ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3016 kInstanceTemplateOffset)
3017ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3018ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003019ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3020 kInstanceCallHandlerOffset)
3021ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3022 kAccessCheckInfoOffset)
3023ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3024
3025ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003026ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3027 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003028
3029ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3030ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3031
3032ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3033
3034ACCESSORS(Script, source, Object, kSourceOffset)
3035ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003036ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003037ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3038ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003039ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003040ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003041ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
3042ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003043ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003044ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003045ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003046ACCESSORS(Script, eval_from_instructions_offset, Smi,
3047 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003048
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003049#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003050ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3051ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3052ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3053ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3054
3055ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3056ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3057ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3058ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003059#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060
3061ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003062ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3063ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003064ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3065 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003066ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3068ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003069ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003070ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3071 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003072
3073BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3074 kHiddenPrototypeBit)
3075BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3076BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3077 kNeedsAccessCheckBit)
3078BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3079 kIsExpressionBit)
3080BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3081 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003082BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003083 has_only_simple_this_property_assignments,
3084 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003085BOOL_ACCESSORS(SharedFunctionInfo,
3086 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003087 allows_lazy_compilation,
3088 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003089
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003090
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003091#if V8_HOST_ARCH_32_BIT
3092SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3093SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003094 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003095SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003097SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3098SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003099 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003100SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3101SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003103SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003104 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003105SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003106 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003108#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003109
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003110#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003111 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003112 int holder::name() { \
3113 int value = READ_INT_FIELD(this, offset); \
3114 ASSERT(kHeapObjectTag == 1); \
3115 ASSERT((value & kHeapObjectTag) == 0); \
3116 return value >> 1; \
3117 } \
3118 void holder::set_##name(int value) { \
3119 ASSERT(kHeapObjectTag == 1); \
3120 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3121 (value & 0xC0000000) == 0x000000000); \
3122 WRITE_INT_FIELD(this, \
3123 offset, \
3124 (value << 1) & ~kHeapObjectTag); \
3125 }
3126
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003127#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3128 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003129 INT_ACCESSORS(holder, name, offset)
3130
3131
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003132PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003133PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3134 formal_parameter_count,
3135 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003136
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003137PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3138 expected_nof_properties,
3139 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003140PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3141
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003142PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3143PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3144 start_position_and_type,
3145 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003146
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003147PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3148 function_token_position,
3149 kFunctionTokenPositionOffset)
3150PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3151 compiler_hints,
3152 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003153
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003154PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3155 this_property_assignments_count,
3156 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003158#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003159
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003160
3161int SharedFunctionInfo::construction_count() {
3162 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3163}
3164
3165
3166void SharedFunctionInfo::set_construction_count(int value) {
3167 ASSERT(0 <= value && value < 256);
3168 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3169}
3170
3171
3172bool SharedFunctionInfo::live_objects_may_exist() {
3173 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3174}
3175
3176
3177void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3178 if (value) {
3179 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3180 } else {
3181 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3182 }
3183}
3184
3185
3186bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003187 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003188}
3189
3190
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191bool SharedFunctionInfo::optimization_disabled() {
3192 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3193}
3194
3195
3196void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3197 set_compiler_hints(BooleanBit::set(compiler_hints(),
3198 kOptimizationDisabled,
3199 disable));
3200 // If disabling optimizations we reflect that in the code object so
3201 // it will not be counted as optimizable code.
3202 if ((code()->kind() == Code::FUNCTION) && disable) {
3203 code()->set_optimizable(false);
3204 }
3205}
3206
3207
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003208bool SharedFunctionInfo::strict_mode() {
3209 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3210}
3211
3212
3213void SharedFunctionInfo::set_strict_mode(bool value) {
3214 set_compiler_hints(BooleanBit::set(compiler_hints(),
3215 kStrictModeFunction,
3216 value));
3217}
3218
3219
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003220ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3221ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3222
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003223bool Script::HasValidSource() {
3224 Object* src = this->source();
3225 if (!src->IsString()) return true;
3226 String* src_str = String::cast(src);
3227 if (!StringShape(src_str).IsExternal()) return true;
3228 if (src_str->IsAsciiRepresentation()) {
3229 return ExternalAsciiString::cast(src)->resource() != NULL;
3230 } else if (src_str->IsTwoByteRepresentation()) {
3231 return ExternalTwoByteString::cast(src)->resource() != NULL;
3232 }
3233 return true;
3234}
3235
3236
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003237void SharedFunctionInfo::DontAdaptArguments() {
3238 ASSERT(code()->kind() == Code::BUILTIN);
3239 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3240}
3241
3242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003243int SharedFunctionInfo::start_position() {
3244 return start_position_and_type() >> kStartPositionShift;
3245}
3246
3247
3248void SharedFunctionInfo::set_start_position(int start_position) {
3249 set_start_position_and_type((start_position << kStartPositionShift)
3250 | (start_position_and_type() & ~kStartPositionMask));
3251}
3252
3253
3254Code* SharedFunctionInfo::code() {
3255 return Code::cast(READ_FIELD(this, kCodeOffset));
3256}
3257
3258
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003259Code* SharedFunctionInfo::unchecked_code() {
3260 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3261}
3262
3263
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003264void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003266 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267}
3268
3269
ager@chromium.orgb5737492010-07-15 09:29:43 +00003270SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3271 return reinterpret_cast<SerializedScopeInfo*>(
3272 READ_FIELD(this, kScopeInfoOffset));
3273}
3274
3275
3276void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3277 WriteBarrierMode mode) {
3278 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003279 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003280}
3281
3282
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003283Smi* SharedFunctionInfo::deopt_counter() {
3284 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3285}
3286
3287
3288void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3289 WRITE_FIELD(this, kDeoptCounterOffset, value);
3290}
3291
3292
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003293bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003294 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003295 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003296}
3297
3298
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003299bool SharedFunctionInfo::IsApiFunction() {
3300 return function_data()->IsFunctionTemplateInfo();
3301}
3302
3303
3304FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3305 ASSERT(IsApiFunction());
3306 return FunctionTemplateInfo::cast(function_data());
3307}
3308
3309
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003310bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003311 return function_data()->IsSmi();
3312}
3313
3314
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003315BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3316 ASSERT(HasBuiltinFunctionId());
3317 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003318}
3319
3320
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003321int SharedFunctionInfo::code_age() {
3322 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3323}
3324
3325
3326void SharedFunctionInfo::set_code_age(int code_age) {
3327 set_compiler_hints(compiler_hints() |
3328 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3329}
3330
3331
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003332bool SharedFunctionInfo::has_deoptimization_support() {
3333 Code* code = this->code();
3334 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3335}
3336
3337
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003338bool JSFunction::IsBuiltin() {
3339 return context()->global()->IsJSBuiltinsObject();
3340}
3341
3342
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343bool JSFunction::NeedsArgumentsAdaption() {
3344 return shared()->formal_parameter_count() !=
3345 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3346}
3347
3348
3349bool JSFunction::IsOptimized() {
3350 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3351}
3352
3353
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003354bool JSFunction::IsOptimizable() {
3355 return code()->kind() == Code::FUNCTION && code()->optimizable();
3356}
3357
3358
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003359bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003360 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003361}
3362
3363
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003365 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366}
3367
3368
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003369Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003370 return reinterpret_cast<Code*>(
3371 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003372}
3373
3374
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003376 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003377 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003378 Address entry = value->entry();
3379 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380}
3381
3382
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003383void JSFunction::ReplaceCode(Code* code) {
3384 bool was_optimized = IsOptimized();
3385 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3386
3387 set_code(code);
3388
3389 // Add/remove the function from the list of optimized functions for this
3390 // context based on the state change.
3391 if (!was_optimized && is_optimized) {
3392 context()->global_context()->AddOptimizedFunction(this);
3393 }
3394 if (was_optimized && !is_optimized) {
3395 context()->global_context()->RemoveOptimizedFunction(this);
3396 }
3397}
3398
3399
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400Context* JSFunction::context() {
3401 return Context::cast(READ_FIELD(this, kContextOffset));
3402}
3403
3404
3405Object* JSFunction::unchecked_context() {
3406 return READ_FIELD(this, kContextOffset);
3407}
3408
3409
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003410SharedFunctionInfo* JSFunction::unchecked_shared() {
3411 return reinterpret_cast<SharedFunctionInfo*>(
3412 READ_FIELD(this, kSharedFunctionInfoOffset));
3413}
3414
3415
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003416void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003417 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418 WRITE_FIELD(this, kContextOffset, value);
3419 WRITE_BARRIER(this, kContextOffset);
3420}
3421
3422ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3423 kPrototypeOrInitialMapOffset)
3424
3425
3426Map* JSFunction::initial_map() {
3427 return Map::cast(prototype_or_initial_map());
3428}
3429
3430
3431void JSFunction::set_initial_map(Map* value) {
3432 set_prototype_or_initial_map(value);
3433}
3434
3435
3436bool JSFunction::has_initial_map() {
3437 return prototype_or_initial_map()->IsMap();
3438}
3439
3440
3441bool JSFunction::has_instance_prototype() {
3442 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3443}
3444
3445
3446bool JSFunction::has_prototype() {
3447 return map()->has_non_instance_prototype() || has_instance_prototype();
3448}
3449
3450
3451Object* JSFunction::instance_prototype() {
3452 ASSERT(has_instance_prototype());
3453 if (has_initial_map()) return initial_map()->prototype();
3454 // When there is no initial map and the prototype is a JSObject, the
3455 // initial map field is used for the prototype field.
3456 return prototype_or_initial_map();
3457}
3458
3459
3460Object* JSFunction::prototype() {
3461 ASSERT(has_prototype());
3462 // If the function's prototype property has been set to a non-JSObject
3463 // value, that value is stored in the constructor field of the map.
3464 if (map()->has_non_instance_prototype()) return map()->constructor();
3465 return instance_prototype();
3466}
3467
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003468bool JSFunction::should_have_prototype() {
3469 return map()->function_with_prototype();
3470}
3471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003472
3473bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003474 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003475}
3476
3477
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003478int JSFunction::NumberOfLiterals() {
3479 return literals()->length();
3480}
3481
3482
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003483Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003484 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003485 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486}
3487
3488
3489void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3490 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003491 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003492 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3493 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3494}
3495
3496
3497Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003498 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003499 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3500}
3501
3502
3503void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3504 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003505 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003506 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003507 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508}
3509
3510
3511Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003512 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003513}
3514
3515
3516void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003517 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518}
3519
3520
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003521ACCESSORS(JSValue, value, Object, kValueOffset)
3522
3523
3524JSValue* JSValue::cast(Object* obj) {
3525 ASSERT(obj->IsJSValue());
3526 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3527 return reinterpret_cast<JSValue*>(obj);
3528}
3529
3530
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003531ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3532ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3533ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3534ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3535ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3536SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3537SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3538
3539
3540JSMessageObject* JSMessageObject::cast(Object* obj) {
3541 ASSERT(obj->IsJSMessageObject());
3542 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3543 return reinterpret_cast<JSMessageObject*>(obj);
3544}
3545
3546
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003548ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003549ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550
3551
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003552byte* Code::instruction_start() {
3553 return FIELD_ADDR(this, kHeaderSize);
3554}
3555
3556
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003557byte* Code::instruction_end() {
3558 return instruction_start() + instruction_size();
3559}
3560
3561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003562int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003563 return RoundUp(instruction_size(), kObjectAlignment);
3564}
3565
3566
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567FixedArray* Code::unchecked_deoptimization_data() {
3568 return reinterpret_cast<FixedArray*>(
3569 READ_FIELD(this, kDeoptimizationDataOffset));
3570}
3571
3572
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003573ByteArray* Code::unchecked_relocation_info() {
3574 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575}
3576
3577
3578byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003579 return unchecked_relocation_info()->GetDataStartAddress();
3580}
3581
3582
3583int Code::relocation_size() {
3584 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003585}
3586
3587
3588byte* Code::entry() {
3589 return instruction_start();
3590}
3591
3592
3593bool Code::contains(byte* pc) {
3594 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003595 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003596}
3597
3598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599ACCESSORS(JSArray, length, Object, kLengthOffset)
3600
3601
ager@chromium.org236ad962008-09-25 09:45:57 +00003602ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003603
3604
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003605JSRegExp::Type JSRegExp::TypeTag() {
3606 Object* data = this->data();
3607 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3608 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3609 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003610}
3611
3612
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003613int JSRegExp::CaptureCount() {
3614 switch (TypeTag()) {
3615 case ATOM:
3616 return 0;
3617 case IRREGEXP:
3618 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3619 default:
3620 UNREACHABLE();
3621 return -1;
3622 }
3623}
3624
3625
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003626JSRegExp::Flags JSRegExp::GetFlags() {
3627 ASSERT(this->data()->IsFixedArray());
3628 Object* data = this->data();
3629 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3630 return Flags(smi->value());
3631}
3632
3633
3634String* JSRegExp::Pattern() {
3635 ASSERT(this->data()->IsFixedArray());
3636 Object* data = this->data();
3637 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3638 return pattern;
3639}
3640
3641
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003642Object* JSRegExp::DataAt(int index) {
3643 ASSERT(TypeTag() != NOT_COMPILED);
3644 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003645}
3646
3647
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003648void JSRegExp::SetDataAt(int index, Object* value) {
3649 ASSERT(TypeTag() != NOT_COMPILED);
3650 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3651 FixedArray::cast(data())->set(index, value);
3652}
3653
3654
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003655JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003656 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003657 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3658 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003659 return FAST_ELEMENTS;
3660 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003661 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003662 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003663 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3664 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003665 ASSERT(array->IsDictionary());
3666 return DICTIONARY_ELEMENTS;
3667 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003668 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003669 if (array->IsExternalArray()) {
3670 switch (array->map()->instance_type()) {
3671 case EXTERNAL_BYTE_ARRAY_TYPE:
3672 return EXTERNAL_BYTE_ELEMENTS;
3673 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3674 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3675 case EXTERNAL_SHORT_ARRAY_TYPE:
3676 return EXTERNAL_SHORT_ELEMENTS;
3677 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3678 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3679 case EXTERNAL_INT_ARRAY_TYPE:
3680 return EXTERNAL_INT_ELEMENTS;
3681 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3682 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003683 case EXTERNAL_FLOAT_ARRAY_TYPE:
3684 return EXTERNAL_FLOAT_ELEMENTS;
3685 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3686 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003687 case EXTERNAL_PIXEL_ARRAY_TYPE:
3688 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003689 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003690 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003691 }
3692 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003693 UNREACHABLE();
3694 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003695}
3696
3697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003698bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003699 return GetElementsKind() == FAST_ELEMENTS;
3700}
3701
3702
3703bool JSObject::HasDictionaryElements() {
3704 return GetElementsKind() == DICTIONARY_ELEMENTS;
3705}
3706
3707
ager@chromium.org3811b432009-10-28 14:53:37 +00003708bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003709 HeapObject* array = elements();
3710 ASSERT(array != NULL);
3711 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003712}
3713
3714
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003715#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3716bool JSObject::HasExternal##name##Elements() { \
3717 HeapObject* array = elements(); \
3718 ASSERT(array != NULL); \
3719 if (!array->IsHeapObject()) \
3720 return false; \
3721 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003722}
3723
3724
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003725EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3726EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3727EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3728EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3729 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3730EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3731EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3732 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3733EXTERNAL_ELEMENTS_CHECK(Float,
3734 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003735EXTERNAL_ELEMENTS_CHECK(Double,
3736 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003737EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003738
3739
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003740bool JSObject::HasNamedInterceptor() {
3741 return map()->has_named_interceptor();
3742}
3743
3744
3745bool JSObject::HasIndexedInterceptor() {
3746 return map()->has_indexed_interceptor();
3747}
3748
3749
ager@chromium.org5c838252010-02-19 08:53:10 +00003750bool JSObject::AllowsSetElementsLength() {
3751 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003752 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003753 return result;
3754}
3755
3756
lrn@chromium.org303ada72010-10-27 09:33:13 +00003757MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003758 ASSERT(HasFastElements());
3759 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003760 Isolate* isolate = GetIsolate();
3761 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003762 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003763 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3764 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003765 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3766 return maybe_writable_elems;
3767 }
3768 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003769 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003770 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003771 return writable_elems;
3772}
3773
3774
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003775StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003777 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003778}
3779
3780
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003781NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003782 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003783 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784}
3785
3786
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003787bool String::IsHashFieldComputed(uint32_t field) {
3788 return (field & kHashNotComputedMask) == 0;
3789}
3790
3791
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003792bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003793 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003794}
3795
3796
3797uint32_t String::Hash() {
3798 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003799 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003800 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003801 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802 return ComputeAndSetHash();
3803}
3804
3805
ager@chromium.org7c537e22008-10-16 08:43:32 +00003806StringHasher::StringHasher(int length)
3807 : length_(length),
3808 raw_running_hash_(0),
3809 array_index_(0),
3810 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3811 is_first_char_(true),
3812 is_valid_(true) { }
3813
3814
3815bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003816 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003817}
3818
3819
3820void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003821 // Use the Jenkins one-at-a-time hash function to update the hash
3822 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003823 raw_running_hash_ += c;
3824 raw_running_hash_ += (raw_running_hash_ << 10);
3825 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003826 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003827 if (is_array_index_) {
3828 if (c < '0' || c > '9') {
3829 is_array_index_ = false;
3830 } else {
3831 int d = c - '0';
3832 if (is_first_char_) {
3833 is_first_char_ = false;
3834 if (c == '0' && length_ > 1) {
3835 is_array_index_ = false;
3836 return;
3837 }
3838 }
3839 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3840 is_array_index_ = false;
3841 } else {
3842 array_index_ = array_index_ * 10 + d;
3843 }
3844 }
3845 }
3846}
3847
3848
3849void StringHasher::AddCharacterNoIndex(uc32 c) {
3850 ASSERT(!is_array_index());
3851 raw_running_hash_ += c;
3852 raw_running_hash_ += (raw_running_hash_ << 10);
3853 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3854}
3855
3856
3857uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003858 // Get the calculated raw hash value and do some more bit ops to distribute
3859 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003860 uint32_t result = raw_running_hash_;
3861 result += (result << 3);
3862 result ^= (result >> 11);
3863 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003864 if (result == 0) {
3865 result = 27;
3866 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003867 return result;
3868}
3869
3870
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003871template <typename schar>
3872uint32_t HashSequentialString(const schar* chars, int length) {
3873 StringHasher hasher(length);
3874 if (!hasher.has_trivial_hash()) {
3875 int i;
3876 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3877 hasher.AddCharacter(chars[i]);
3878 }
3879 for (; i < length; i++) {
3880 hasher.AddCharacterNoIndex(chars[i]);
3881 }
3882 }
3883 return hasher.GetHashField();
3884}
3885
3886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003888 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003889 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3890 return false;
3891 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003892 return SlowAsArrayIndex(index);
3893}
3894
3895
3896Object* JSObject::GetPrototype() {
3897 return JSObject::cast(this)->map()->prototype();
3898}
3899
3900
3901PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3902 return GetPropertyAttributeWithReceiver(this, key);
3903}
3904
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003905// TODO(504): this may be useful in other places too where JSGlobalProxy
3906// is used.
3907Object* JSObject::BypassGlobalProxy() {
3908 if (IsJSGlobalProxy()) {
3909 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003910 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003911 ASSERT(proto->IsJSGlobalObject());
3912 return proto;
3913 }
3914 return this;
3915}
3916
3917
3918bool JSObject::HasHiddenPropertiesObject() {
3919 ASSERT(!IsJSGlobalProxy());
3920 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003921 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003922 false) != ABSENT;
3923}
3924
3925
3926Object* JSObject::GetHiddenPropertiesObject() {
3927 ASSERT(!IsJSGlobalProxy());
3928 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003929 // You can't install a getter on a property indexed by the hidden symbol,
3930 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3931 // object.
3932 Object* result =
3933 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003934 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00003935 &attributes)->ToObjectUnchecked();
3936 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003937}
3938
3939
lrn@chromium.org303ada72010-10-27 09:33:13 +00003940MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003941 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003942 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003943 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003944 DONT_ENUM,
3945 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003946}
3947
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003948
3949bool JSObject::HasElement(uint32_t index) {
3950 return HasElementWithReceiver(this, index);
3951}
3952
3953
3954bool AccessorInfo::all_can_read() {
3955 return BooleanBit::get(flag(), kAllCanReadBit);
3956}
3957
3958
3959void AccessorInfo::set_all_can_read(bool value) {
3960 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3961}
3962
3963
3964bool AccessorInfo::all_can_write() {
3965 return BooleanBit::get(flag(), kAllCanWriteBit);
3966}
3967
3968
3969void AccessorInfo::set_all_can_write(bool value) {
3970 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3971}
3972
3973
ager@chromium.org870a0b62008-11-04 11:43:05 +00003974bool AccessorInfo::prohibits_overwriting() {
3975 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3976}
3977
3978
3979void AccessorInfo::set_prohibits_overwriting(bool value) {
3980 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3981}
3982
3983
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003984PropertyAttributes AccessorInfo::property_attributes() {
3985 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3986}
3987
3988
3989void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3990 ASSERT(AttributesField::is_valid(attributes));
3991 int rest_value = flag()->value() & ~AttributesField::mask();
3992 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3993}
3994
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003995
3996template<typename Shape, typename Key>
3997void Dictionary<Shape, Key>::SetEntry(int entry,
3998 Object* key,
3999 Object* value) {
4000 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4001}
4002
4003
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004004template<typename Shape, typename Key>
4005void Dictionary<Shape, Key>::SetEntry(int entry,
4006 Object* key,
4007 Object* value,
4008 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004009 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004010 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004011 AssertNoAllocation no_gc;
4012 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004013 FixedArray::set(index, key, mode);
4014 FixedArray::set(index+1, value, mode);
4015 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004016}
4017
4018
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004019bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4020 ASSERT(other->IsNumber());
4021 return key == static_cast<uint32_t>(other->Number());
4022}
4023
4024
4025uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4026 return ComputeIntegerHash(key);
4027}
4028
4029
4030uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4031 ASSERT(other->IsNumber());
4032 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4033}
4034
4035
4036MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4037 return Isolate::Current()->heap()->NumberFromUint32(key);
4038}
4039
4040
4041bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4042 // We know that all entries in a hash table had their hash keys created.
4043 // Use that knowledge to have fast failure.
4044 if (key->Hash() != String::cast(other)->Hash()) return false;
4045 return key->Equals(String::cast(other));
4046}
4047
4048
4049uint32_t StringDictionaryShape::Hash(String* key) {
4050 return key->Hash();
4051}
4052
4053
4054uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4055 return String::cast(other)->Hash();
4056}
4057
4058
4059MaybeObject* StringDictionaryShape::AsObject(String* key) {
4060 return key;
4061}
4062
4063
4064void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004065 // No write barrier is needed since empty_fixed_array is not in new space.
4066 // Please note this function is used during marking:
4067 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004068 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4069 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004070}
4071
4072
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004073void JSArray::EnsureSize(int required_size) {
4074 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004075 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004076 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4077 if (elts->length() < required_size) {
4078 // Doubling in size would be overkill, but leave some slack to avoid
4079 // constantly growing.
4080 Expand(required_size + (required_size >> 3));
4081 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004082 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004083 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4084 // Expand will allocate a new backing store in new space even if the size
4085 // we asked for isn't larger than what we had before.
4086 Expand(required_size);
4087 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004088}
4089
4090
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004091void JSArray::set_length(Smi* length) {
4092 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4093}
4094
4095
ager@chromium.org7c537e22008-10-16 08:43:32 +00004096void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004097 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004098 set_elements(storage);
4099}
4100
4101
lrn@chromium.org303ada72010-10-27 09:33:13 +00004102MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004103 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004104 return GetHeap()->CopyFixedArray(this);
4105}
4106
4107
4108Relocatable::Relocatable(Isolate* isolate) {
4109 ASSERT(isolate == Isolate::Current());
4110 isolate_ = isolate;
4111 prev_ = isolate->relocatable_top();
4112 isolate->set_relocatable_top(this);
4113}
4114
4115
4116Relocatable::~Relocatable() {
4117 ASSERT(isolate_ == Isolate::Current());
4118 ASSERT_EQ(isolate_->relocatable_top(), this);
4119 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004120}
4121
4122
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004123int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4124 return map->instance_size();
4125}
4126
4127
4128void Proxy::ProxyIterateBody(ObjectVisitor* v) {
4129 v->VisitExternalReference(
4130 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4131}
4132
4133
4134template<typename StaticVisitor>
4135void Proxy::ProxyIterateBody() {
4136 StaticVisitor::VisitExternalReference(
4137 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4138}
4139
4140
4141void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4142 typedef v8::String::ExternalAsciiStringResource Resource;
4143 v->VisitExternalAsciiString(
4144 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4145}
4146
4147
4148template<typename StaticVisitor>
4149void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4150 typedef v8::String::ExternalAsciiStringResource Resource;
4151 StaticVisitor::VisitExternalAsciiString(
4152 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4153}
4154
4155
4156void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4157 typedef v8::String::ExternalStringResource Resource;
4158 v->VisitExternalTwoByteString(
4159 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4160}
4161
4162
4163template<typename StaticVisitor>
4164void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4165 typedef v8::String::ExternalStringResource Resource;
4166 StaticVisitor::VisitExternalTwoByteString(
4167 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4168}
4169
4170#define SLOT_ADDR(obj, offset) \
4171 reinterpret_cast<Object**>((obj)->address() + offset)
4172
4173template<int start_offset, int end_offset, int size>
4174void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4175 HeapObject* obj,
4176 ObjectVisitor* v) {
4177 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4178}
4179
4180
4181template<int start_offset>
4182void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4183 int object_size,
4184 ObjectVisitor* v) {
4185 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4186}
4187
4188#undef SLOT_ADDR
4189
4190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004191#undef CAST_ACCESSOR
4192#undef INT_ACCESSORS
4193#undef SMI_ACCESSORS
4194#undef ACCESSORS
4195#undef FIELD_ADDR
4196#undef READ_FIELD
4197#undef WRITE_FIELD
4198#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004199#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004200#undef READ_MEMADDR_FIELD
4201#undef WRITE_MEMADDR_FIELD
4202#undef READ_DOUBLE_FIELD
4203#undef WRITE_DOUBLE_FIELD
4204#undef READ_INT_FIELD
4205#undef WRITE_INT_FIELD
4206#undef READ_SHORT_FIELD
4207#undef WRITE_SHORT_FIELD
4208#undef READ_BYTE_FIELD
4209#undef WRITE_BYTE_FIELD
4210
4211
4212} } // namespace v8::internal
4213
4214#endif // V8_OBJECTS_INL_H_