blob: 841fcbc0f335d12d4f97d0cd45cd0c2673acf59a [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
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000587bool Object::IsJSProxy() {
588 return Object::IsHeapObject()
589 && HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE;
590}
591
592
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000593bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000595 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596}
597
598
599bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000600 return IsOddball() &&
601 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602}
603
604
605bool Object::IsJSArray() {
606 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000607 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608}
609
610
ager@chromium.org236ad962008-09-25 09:45:57 +0000611bool Object::IsJSRegExp() {
612 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000613 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000614}
615
616
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000617template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618 return obj->IsJSArray();
619}
620
621
622bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000623 return Object::IsHeapObject() &&
624 HeapObject::cast(this)->map() ==
625 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000630 return IsHashTable() && this !=
631 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
635bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 return IsHashTable() && this ==
637 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
ager@chromium.orgac091b72010-05-05 07:34:42 +0000641bool Object::IsJSFunctionResultCache() {
642 if (!IsFixedArray()) return false;
643 FixedArray* self = FixedArray::cast(this);
644 int length = self->length();
645 if (length < JSFunctionResultCache::kEntriesIndex) return false;
646 if ((length - JSFunctionResultCache::kEntriesIndex)
647 % JSFunctionResultCache::kEntrySize != 0) {
648 return false;
649 }
650#ifdef DEBUG
651 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
652#endif
653 return true;
654}
655
656
ricow@chromium.org65fae842010-08-25 15:26:24 +0000657bool Object::IsNormalizedMapCache() {
658 if (!IsFixedArray()) return false;
659 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
660 return false;
661 }
662#ifdef DEBUG
663 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
664#endif
665 return true;
666}
667
668
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000669bool Object::IsCompilationCacheTable() {
670 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000671}
672
673
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000674bool Object::IsCodeCacheHashTable() {
675 return IsHashTable();
676}
677
678
ager@chromium.org236ad962008-09-25 09:45:57 +0000679bool Object::IsMapCache() {
680 return IsHashTable();
681}
682
683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684bool Object::IsPrimitive() {
685 return IsOddball() || IsNumber() || IsString();
686}
687
688
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689bool Object::IsJSGlobalProxy() {
690 bool result = IsHeapObject() &&
691 (HeapObject::cast(this)->map()->instance_type() ==
692 JS_GLOBAL_PROXY_TYPE);
693 ASSERT(!result || IsAccessCheckNeeded());
694 return result;
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000699 if (!IsHeapObject()) return false;
700
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000701 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000702 return type == JS_GLOBAL_OBJECT_TYPE ||
703 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704}
705
706
707bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708 return IsHeapObject() &&
709 (HeapObject::cast(this)->map()->instance_type() ==
710 JS_GLOBAL_OBJECT_TYPE);
711}
712
713
714bool Object::IsJSBuiltinsObject() {
715 return IsHeapObject() &&
716 (HeapObject::cast(this)->map()->instance_type() ==
717 JS_BUILTINS_OBJECT_TYPE);
718}
719
720
721bool Object::IsUndetectableObject() {
722 return IsHeapObject()
723 && HeapObject::cast(this)->map()->is_undetectable();
724}
725
726
727bool Object::IsAccessCheckNeeded() {
728 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000729 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730}
731
732
733bool Object::IsStruct() {
734 if (!IsHeapObject()) return false;
735 switch (HeapObject::cast(this)->map()->instance_type()) {
736#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
737 STRUCT_LIST(MAKE_STRUCT_CASE)
738#undef MAKE_STRUCT_CASE
739 default: return false;
740 }
741}
742
743
744#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
745 bool Object::Is##Name() { \
746 return Object::IsHeapObject() \
747 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
748 }
749 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
750#undef MAKE_STRUCT_PREDICATE
751
752
753bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000754 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755}
756
757
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000758bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
760}
761
762
763bool Object::IsTheHole() {
764 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765}
766
767
768bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000769 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770}
771
772
773bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000774 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000775}
776
777
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000778bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000779 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780}
781
782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783double Object::Number() {
784 ASSERT(IsNumber());
785 return IsSmi()
786 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
787 : reinterpret_cast<HeapNumber*>(this)->value();
788}
789
790
lrn@chromium.org303ada72010-10-27 09:33:13 +0000791MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792 if (IsSmi()) return this;
793 if (IsHeapNumber()) {
794 double value = HeapNumber::cast(this)->value();
795 int int_value = FastD2I(value);
796 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
797 return Smi::FromInt(int_value);
798 }
799 }
800 return Failure::Exception();
801}
802
803
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000804bool Object::HasSpecificClassOf(String* name) {
805 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
806}
807
808
lrn@chromium.org303ada72010-10-27 09:33:13 +0000809MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000810 // GetElement can trigger a getter which can cause allocation.
811 // This was not always the case. This ASSERT is here to catch
812 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000813 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814 return GetElementWithReceiver(this, index);
815}
816
817
lrn@chromium.org303ada72010-10-27 09:33:13 +0000818Object* Object::GetElementNoExceptionThrown(uint32_t index) {
819 MaybeObject* maybe = GetElementWithReceiver(this, index);
820 ASSERT(!maybe->IsFailure());
821 Object* result = NULL; // Initialization to please compiler.
822 maybe->ToObject(&result);
823 return result;
824}
825
826
827MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 PropertyAttributes attributes;
829 return GetPropertyWithReceiver(this, key, &attributes);
830}
831
832
lrn@chromium.org303ada72010-10-27 09:33:13 +0000833MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834 return GetPropertyWithReceiver(this, key, attributes);
835}
836
837
838#define FIELD_ADDR(p, offset) \
839 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
840
841#define READ_FIELD(p, offset) \
842 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
843
844#define WRITE_FIELD(p, offset, value) \
845 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
846
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000847// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000848#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000851// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000852// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000853#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000854 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000855 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000856 } else { \
857 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858 ASSERT(heap->InNewSpace(object) || \
859 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000860 Page::FromAddress(object->address())-> \
861 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000862 }
863
lrn@chromium.org7516f052011-03-30 08:52:27 +0000864#ifndef V8_TARGET_ARCH_MIPS
865 #define READ_DOUBLE_FIELD(p, offset) \
866 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
867#else // V8_TARGET_ARCH_MIPS
868 // Prevent gcc from using load-double (mips ldc1) on (possibly)
869 // non-64-bit aligned HeapNumber::value.
870 static inline double read_double_field(HeapNumber* p, int offset) {
871 union conversion {
872 double d;
873 uint32_t u[2];
874 } c;
875 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
876 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
877 return c.d;
878 }
879 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
880#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000881
lrn@chromium.org7516f052011-03-30 08:52:27 +0000882
883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
889 static inline void write_double_field(HeapNumber* p, int offset,
890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
1077bool MapWord::IsMarked() {
1078 return (value_ & kMarkingMask) == 0;
1079}
1080
1081
1082void MapWord::SetMark() {
1083 value_ &= ~kMarkingMask;
1084}
1085
1086
1087void MapWord::ClearMark() {
1088 value_ |= kMarkingMask;
1089}
1090
1091
1092bool MapWord::IsOverflowed() {
1093 return (value_ & kOverflowMask) != 0;
1094}
1095
1096
1097void MapWord::SetOverflow() {
1098 value_ |= kOverflowMask;
1099}
1100
1101
1102void MapWord::ClearOverflow() {
1103 value_ &= ~kOverflowMask;
1104}
1105
1106
1107MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1108 // Offset is the distance in live bytes from the first live object in the
1109 // same page. The offset between two objects in the same page should not
1110 // exceed the object area size of a page.
1111 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1112
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001113 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001114 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1115
1116 Page* map_page = Page::FromAddress(map_address);
1117 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1118
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001119 uintptr_t map_page_offset =
1120 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001121
1122 uintptr_t encoding =
1123 (compact_offset << kForwardingOffsetShift) |
1124 (map_page_offset << kMapPageOffsetShift) |
1125 (map_page->mc_page_index << kMapPageIndexShift);
1126 return MapWord(encoding);
1127}
1128
1129
1130Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001131 int map_page_index =
1132 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001133 ASSERT_MAP_PAGE_INDEX(map_page_index);
1134
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001135 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001136 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1137 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001138
1139 return (map_space->PageAddress(map_page_index) + map_page_offset);
1140}
1141
1142
1143int MapWord::DecodeOffset() {
1144 // The offset field is represented in the kForwardingOffsetBits
1145 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001146 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1147 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1148 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001149}
1150
1151
1152MapWord MapWord::FromEncodedAddress(Address address) {
1153 return MapWord(reinterpret_cast<uintptr_t>(address));
1154}
1155
1156
1157Address MapWord::ToEncodedAddress() {
1158 return reinterpret_cast<Address>(value_);
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162#ifdef DEBUG
1163void HeapObject::VerifyObjectField(int offset) {
1164 VerifyPointer(READ_FIELD(this, offset));
1165}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001166
1167void HeapObject::VerifySmiField(int offset) {
1168 ASSERT(READ_FIELD(this, offset)->IsSmi());
1169}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001170#endif
1171
1172
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001173Heap* HeapObject::GetHeap() {
1174 // During GC, the map pointer in HeapObject is used in various ways that
1175 // prevent us from retrieving Heap from the map.
1176 // Assert that we are not in GC, implement GC code in a way that it doesn't
1177 // pull heap from the map.
1178 ASSERT(HEAP->is_safe_to_read_maps());
1179 return map()->heap();
1180}
1181
1182
1183Isolate* HeapObject::GetIsolate() {
1184 return GetHeap()->isolate();
1185}
1186
1187
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001189 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190}
1191
1192
1193void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001194 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195}
1196
1197
kasper.lund7276f142008-07-30 08:49:36 +00001198MapWord HeapObject::map_word() {
1199 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1200}
1201
1202
1203void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001204 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001205 // here.
1206 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1207}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001208
1209
1210HeapObject* HeapObject::FromAddress(Address address) {
1211 ASSERT_TAG_ALIGNED(address);
1212 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1213}
1214
1215
1216Address HeapObject::address() {
1217 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1218}
1219
1220
1221int HeapObject::Size() {
1222 return SizeFromMap(map());
1223}
1224
1225
1226void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1227 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1228 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1229}
1230
1231
1232void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1233 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1234}
1235
1236
kasper.lund7276f142008-07-30 08:49:36 +00001237bool HeapObject::IsMarked() {
1238 return map_word().IsMarked();
1239}
1240
1241
1242void HeapObject::SetMark() {
1243 ASSERT(!IsMarked());
1244 MapWord first_word = map_word();
1245 first_word.SetMark();
1246 set_map_word(first_word);
1247}
1248
1249
1250void HeapObject::ClearMark() {
1251 ASSERT(IsMarked());
1252 MapWord first_word = map_word();
1253 first_word.ClearMark();
1254 set_map_word(first_word);
1255}
1256
1257
1258bool HeapObject::IsOverflowed() {
1259 return map_word().IsOverflowed();
1260}
1261
1262
1263void HeapObject::SetOverflow() {
1264 MapWord first_word = map_word();
1265 first_word.SetOverflow();
1266 set_map_word(first_word);
1267}
1268
1269
1270void HeapObject::ClearOverflow() {
1271 ASSERT(IsOverflowed());
1272 MapWord first_word = map_word();
1273 first_word.ClearOverflow();
1274 set_map_word(first_word);
1275}
1276
1277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278double HeapNumber::value() {
1279 return READ_DOUBLE_FIELD(this, kValueOffset);
1280}
1281
1282
1283void HeapNumber::set_value(double value) {
1284 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1285}
1286
1287
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001288int HeapNumber::get_exponent() {
1289 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1290 kExponentShift) - kExponentBias;
1291}
1292
1293
1294int HeapNumber::get_sign() {
1295 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1296}
1297
1298
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001299ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001300
1301
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001302HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001303 Object* array = READ_FIELD(this, kElementsOffset);
1304 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001305 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001306 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001307}
1308
1309
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001310void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001311 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001312 (value->map() == GetHeap()->fixed_array_map() ||
1313 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001314 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001315 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001316 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001317 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001318}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319
1320
1321void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001322 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1323 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324}
1325
1326
1327void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001328 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1330 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331}
1332
1333
lrn@chromium.org303ada72010-10-27 09:33:13 +00001334MaybeObject* JSObject::ResetElements() {
1335 Object* obj;
1336 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1337 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1338 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001339 set_map(Map::cast(obj));
1340 initialize_elements();
1341 return this;
1342}
1343
1344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001345ACCESSORS(Oddball, to_string, String, kToStringOffset)
1346ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1347
1348
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001349byte Oddball::kind() {
1350 return READ_BYTE_FIELD(this, kKindOffset);
1351}
1352
1353
1354void Oddball::set_kind(byte value) {
1355 WRITE_BYTE_FIELD(this, kKindOffset, value);
1356}
1357
1358
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001359Object* JSGlobalPropertyCell::value() {
1360 return READ_FIELD(this, kValueOffset);
1361}
1362
1363
1364void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1365 // The write barrier is not used for global property cells.
1366 ASSERT(!val->IsJSGlobalPropertyCell());
1367 WRITE_FIELD(this, kValueOffset, val);
1368}
1369
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001372 InstanceType type = map()->instance_type();
1373 // Check for the most common kind of JavaScript object before
1374 // falling into the generic switch. This speeds up the internal
1375 // field operations considerably on average.
1376 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1377 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001378 case JS_GLOBAL_PROXY_TYPE:
1379 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 case JS_GLOBAL_OBJECT_TYPE:
1381 return JSGlobalObject::kSize;
1382 case JS_BUILTINS_OBJECT_TYPE:
1383 return JSBuiltinsObject::kSize;
1384 case JS_FUNCTION_TYPE:
1385 return JSFunction::kSize;
1386 case JS_VALUE_TYPE:
1387 return JSValue::kSize;
1388 case JS_ARRAY_TYPE:
1389 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001390 case JS_REGEXP_TYPE:
1391 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001392 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001393 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001394 case JS_MESSAGE_OBJECT_TYPE:
1395 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396 default:
1397 UNREACHABLE();
1398 return 0;
1399 }
1400}
1401
1402
1403int JSObject::GetInternalFieldCount() {
1404 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001405 // Make sure to adjust for the number of in-object properties. These
1406 // properties do contribute to the size, but are not internal fields.
1407 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1408 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409}
1410
1411
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001412int JSObject::GetInternalFieldOffset(int index) {
1413 ASSERT(index < GetInternalFieldCount() && index >= 0);
1414 return GetHeaderSize() + (kPointerSize * index);
1415}
1416
1417
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418Object* JSObject::GetInternalField(int index) {
1419 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001420 // Internal objects do follow immediately after the header, whereas in-object
1421 // properties are at the end of the object. Therefore there is no need
1422 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1424}
1425
1426
1427void JSObject::SetInternalField(int index, Object* value) {
1428 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001429 // Internal objects do follow immediately after the header, whereas in-object
1430 // properties are at the end of the object. Therefore there is no need
1431 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432 int offset = GetHeaderSize() + (kPointerSize * index);
1433 WRITE_FIELD(this, offset, value);
1434 WRITE_BARRIER(this, offset);
1435}
1436
1437
ager@chromium.org7c537e22008-10-16 08:43:32 +00001438// Access fast-case object properties at index. The use of these routines
1439// is needed to correctly distinguish between properties stored in-object and
1440// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001441Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001442 // Adjust for the number of properties stored in the object.
1443 index -= map()->inobject_properties();
1444 if (index < 0) {
1445 int offset = map()->instance_size() + (index * kPointerSize);
1446 return READ_FIELD(this, offset);
1447 } else {
1448 ASSERT(index < properties()->length());
1449 return properties()->get(index);
1450 }
1451}
1452
1453
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001454Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455 // Adjust for the number of properties stored in the object.
1456 index -= map()->inobject_properties();
1457 if (index < 0) {
1458 int offset = map()->instance_size() + (index * kPointerSize);
1459 WRITE_FIELD(this, offset, value);
1460 WRITE_BARRIER(this, offset);
1461 } else {
1462 ASSERT(index < properties()->length());
1463 properties()->set(index, value);
1464 }
1465 return value;
1466}
1467
1468
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001469int JSObject::GetInObjectPropertyOffset(int index) {
1470 // Adjust for the number of properties stored in the object.
1471 index -= map()->inobject_properties();
1472 ASSERT(index < 0);
1473 return map()->instance_size() + (index * kPointerSize);
1474}
1475
1476
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001477Object* JSObject::InObjectPropertyAt(int index) {
1478 // Adjust for the number of properties stored in the object.
1479 index -= map()->inobject_properties();
1480 ASSERT(index < 0);
1481 int offset = map()->instance_size() + (index * kPointerSize);
1482 return READ_FIELD(this, offset);
1483}
1484
1485
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001486Object* JSObject::InObjectPropertyAtPut(int index,
1487 Object* value,
1488 WriteBarrierMode mode) {
1489 // Adjust for the number of properties stored in the object.
1490 index -= map()->inobject_properties();
1491 ASSERT(index < 0);
1492 int offset = map()->instance_size() + (index * kPointerSize);
1493 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001494 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001495 return value;
1496}
1497
1498
1499
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001500void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001501 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001504 }
1505}
1506
1507
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001508bool JSObject::HasFastProperties() {
1509 return !properties()->IsDictionary();
1510}
1511
1512
1513int JSObject::MaxFastProperties() {
1514 // Allow extra fast properties if the object has more than
1515 // kMaxFastProperties in-object properties. When this is the case,
1516 // it is very unlikely that the object is being used as a dictionary
1517 // and there is a good chance that allowing more map transitions
1518 // will be worth it.
1519 return Max(map()->inobject_properties(), kMaxFastProperties);
1520}
1521
1522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001524 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001525 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001526 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001527 }
1528}
1529
1530
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001531bool Object::ToArrayIndex(uint32_t* index) {
1532 if (IsSmi()) {
1533 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001534 if (value < 0) return false;
1535 *index = value;
1536 return true;
1537 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001538 if (IsHeapNumber()) {
1539 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540 uint32_t uint_value = static_cast<uint32_t>(value);
1541 if (value == static_cast<double>(uint_value)) {
1542 *index = uint_value;
1543 return true;
1544 }
1545 }
1546 return false;
1547}
1548
1549
1550bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1551 if (!this->IsJSValue()) return false;
1552
1553 JSValue* js_value = JSValue::cast(this);
1554 if (!js_value->value()->IsString()) return false;
1555
1556 String* str = String::cast(js_value->value());
1557 if (index >= (uint32_t)str->length()) return false;
1558
1559 return true;
1560}
1561
1562
1563Object* FixedArray::get(int index) {
1564 ASSERT(index >= 0 && index < this->length());
1565 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1566}
1567
1568
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001569void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001570 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001571 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1572 int offset = kHeaderSize + index * kPointerSize;
1573 WRITE_FIELD(this, offset, value);
1574}
1575
1576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001577void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001578 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 ASSERT(index >= 0 && index < this->length());
1580 int offset = kHeaderSize + index * kPointerSize;
1581 WRITE_FIELD(this, offset, value);
1582 WRITE_BARRIER(this, offset);
1583}
1584
1585
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001586WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001587 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001588 return UPDATE_WRITE_BARRIER;
1589}
1590
1591
1592void FixedArray::set(int index,
1593 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001594 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001595 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 ASSERT(index >= 0 && index < this->length());
1597 int offset = kHeaderSize + index * kPointerSize;
1598 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001599 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001600}
1601
1602
1603void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001604 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001606 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1608}
1609
1610
1611void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001612 ASSERT(map() != HEAP->fixed_cow_array_map());
1613 set_undefined(GetHeap(), index);
1614}
1615
1616
1617void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001618 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001619 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001621 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622}
1623
1624
ager@chromium.org236ad962008-09-25 09:45:57 +00001625void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001626 set_null(GetHeap(), index);
1627}
1628
1629
1630void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001631 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001632 ASSERT(!heap->InNewSpace(heap->null_value()));
1633 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001634}
1635
1636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001638 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001640 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1641 WRITE_FIELD(this,
1642 kHeaderSize + index * kPointerSize,
1643 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644}
1645
1646
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001647void FixedArray::set_unchecked(int index, Smi* value) {
1648 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1649 int offset = kHeaderSize + index * kPointerSize;
1650 WRITE_FIELD(this, offset, value);
1651}
1652
1653
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001654void FixedArray::set_unchecked(Heap* heap,
1655 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001656 Object* value,
1657 WriteBarrierMode mode) {
1658 int offset = kHeaderSize + index * kPointerSize;
1659 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001660 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001661}
1662
1663
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001664void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001665 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001666 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1667 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001668}
1669
1670
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001671Object** FixedArray::data_start() {
1672 return HeapObject::RawField(this, kHeaderSize);
1673}
1674
1675
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001676bool DescriptorArray::IsEmpty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001677 ASSERT(this->length() > kFirstIndex ||
1678 this == HEAP->empty_descriptor_array());
1679 return length() <= kFirstIndex;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001680}
1681
1682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001683void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1684 Object* tmp = array->get(first);
1685 fast_set(array, first, array->get(second));
1686 fast_set(array, second, tmp);
1687}
1688
1689
1690int DescriptorArray::Search(String* name) {
1691 SLOW_ASSERT(IsSortedNoDuplicates());
1692
1693 // Check for empty descriptor array.
1694 int nof = number_of_descriptors();
1695 if (nof == 0) return kNotFound;
1696
1697 // Fast case: do linear search for small arrays.
1698 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001699 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001700 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 }
1702
1703 // Slow case: perform binary search.
1704 return BinarySearch(name, 0, nof - 1);
1705}
1706
1707
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001708int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001710 if (number == DescriptorLookupCache::kAbsent) {
1711 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001712 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001713 }
1714 return number;
1715}
1716
1717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001718String* DescriptorArray::GetKey(int descriptor_number) {
1719 ASSERT(descriptor_number < number_of_descriptors());
1720 return String::cast(get(ToKeyIndex(descriptor_number)));
1721}
1722
1723
1724Object* DescriptorArray::GetValue(int descriptor_number) {
1725 ASSERT(descriptor_number < number_of_descriptors());
1726 return GetContentArray()->get(ToValueIndex(descriptor_number));
1727}
1728
1729
1730Smi* DescriptorArray::GetDetails(int descriptor_number) {
1731 ASSERT(descriptor_number < number_of_descriptors());
1732 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1733}
1734
1735
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001736PropertyType DescriptorArray::GetType(int descriptor_number) {
1737 ASSERT(descriptor_number < number_of_descriptors());
1738 return PropertyDetails(GetDetails(descriptor_number)).type();
1739}
1740
1741
1742int DescriptorArray::GetFieldIndex(int descriptor_number) {
1743 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1744}
1745
1746
1747JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1748 return JSFunction::cast(GetValue(descriptor_number));
1749}
1750
1751
1752Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1753 ASSERT(GetType(descriptor_number) == CALLBACKS);
1754 return GetValue(descriptor_number);
1755}
1756
1757
1758AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1759 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001760 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1761 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001762}
1763
1764
1765bool DescriptorArray::IsProperty(int descriptor_number) {
1766 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1767}
1768
1769
1770bool DescriptorArray::IsTransition(int descriptor_number) {
1771 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001772 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1773 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001774}
1775
1776
1777bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1778 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1779}
1780
1781
1782bool DescriptorArray::IsDontEnum(int descriptor_number) {
1783 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1784}
1785
1786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1788 desc->Init(GetKey(descriptor_number),
1789 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001790 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791}
1792
1793
1794void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1795 // Range check.
1796 ASSERT(descriptor_number < number_of_descriptors());
1797
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001798 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001799 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1800 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801
1802 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1803 FixedArray* content_array = GetContentArray();
1804 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1805 fast_set(content_array, ToDetailsIndex(descriptor_number),
1806 desc->GetDetails().AsSmi());
1807}
1808
1809
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001810void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1811 Descriptor desc;
1812 src->Get(src_index, &desc);
1813 Set(index, &desc);
1814}
1815
1816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817void DescriptorArray::Swap(int first, int second) {
1818 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1819 FixedArray* content_array = GetContentArray();
1820 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1821 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1822}
1823
1824
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825template<typename Shape, typename Key>
1826int HashTable<Shape, Key>::FindEntry(Key key) {
1827 return FindEntry(GetIsolate(), key);
1828}
1829
1830
1831// Find entry for key otherwise return kNotFound.
1832template<typename Shape, typename Key>
1833int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1834 uint32_t capacity = Capacity();
1835 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1836 uint32_t count = 1;
1837 // EnsureCapacity will guarantee the hash table is never full.
1838 while (true) {
1839 Object* element = KeyAt(entry);
1840 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1841 if (element != isolate->heap()->null_value() &&
1842 Shape::IsMatch(key, element)) return entry;
1843 entry = NextProbe(entry, count++, capacity);
1844 }
1845 return kNotFound;
1846}
1847
1848
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001849bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001850 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 if (!max_index_object->IsSmi()) return false;
1852 return 0 !=
1853 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1854}
1855
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001856uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001857 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001858 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001859 if (!max_index_object->IsSmi()) return 0;
1860 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1861 return value >> kRequiresSlowElementsTagSize;
1862}
1863
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001864void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001865 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001866}
1867
1868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869// ------------------------------------
1870// Cast operations
1871
1872
1873CAST_ACCESSOR(FixedArray)
1874CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875CAST_ACCESSOR(DeoptimizationInputData)
1876CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001878CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001879CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001880CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001881CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001882CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883CAST_ACCESSOR(String)
1884CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001885CAST_ACCESSOR(SeqAsciiString)
1886CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001887CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888CAST_ACCESSOR(ExternalString)
1889CAST_ACCESSOR(ExternalAsciiString)
1890CAST_ACCESSOR(ExternalTwoByteString)
1891CAST_ACCESSOR(JSObject)
1892CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893CAST_ACCESSOR(HeapObject)
1894CAST_ACCESSOR(HeapNumber)
1895CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001896CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001897CAST_ACCESSOR(SharedFunctionInfo)
1898CAST_ACCESSOR(Map)
1899CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001900CAST_ACCESSOR(GlobalObject)
1901CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001902CAST_ACCESSOR(JSGlobalObject)
1903CAST_ACCESSOR(JSBuiltinsObject)
1904CAST_ACCESSOR(Code)
1905CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001906CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001907CAST_ACCESSOR(JSProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001908CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001910CAST_ACCESSOR(ExternalArray)
1911CAST_ACCESSOR(ExternalByteArray)
1912CAST_ACCESSOR(ExternalUnsignedByteArray)
1913CAST_ACCESSOR(ExternalShortArray)
1914CAST_ACCESSOR(ExternalUnsignedShortArray)
1915CAST_ACCESSOR(ExternalIntArray)
1916CAST_ACCESSOR(ExternalUnsignedIntArray)
1917CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001918CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001919CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920CAST_ACCESSOR(Struct)
1921
1922
1923#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1924 STRUCT_LIST(MAKE_STRUCT_CAST)
1925#undef MAKE_STRUCT_CAST
1926
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001927
1928template <typename Shape, typename Key>
1929HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930 ASSERT(obj->IsHashTable());
1931 return reinterpret_cast<HashTable*>(obj);
1932}
1933
1934
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001935SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1936SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1937
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001938INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939
1940
ager@chromium.orgac091b72010-05-05 07:34:42 +00001941SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001942
1943
1944uint32_t String::hash_field() {
1945 return READ_UINT32_FIELD(this, kHashFieldOffset);
1946}
1947
1948
1949void String::set_hash_field(uint32_t value) {
1950 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001951#if V8_HOST_ARCH_64_BIT
1952 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1953#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001954}
1955
1956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001957bool String::Equals(String* other) {
1958 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001959 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1960 return false;
1961 }
1962 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963}
1964
1965
lrn@chromium.org303ada72010-10-27 09:33:13 +00001966MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001967 if (!StringShape(this).IsCons()) return this;
1968 ConsString* cons = ConsString::cast(this);
1969 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001970 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001971}
1972
1973
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001974String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001975 MaybeObject* flat = TryFlatten(pretenure);
1976 Object* successfully_flattened;
1977 if (flat->ToObject(&successfully_flattened)) {
1978 return String::cast(successfully_flattened);
1979 }
1980 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001981}
1982
1983
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001984uint16_t String::Get(int index) {
1985 ASSERT(index >= 0 && index < length());
1986 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001987 case kSeqStringTag | kAsciiStringTag:
1988 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1989 case kSeqStringTag | kTwoByteStringTag:
1990 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1991 case kConsStringTag | kAsciiStringTag:
1992 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001993 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001994 case kExternalStringTag | kAsciiStringTag:
1995 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1996 case kExternalStringTag | kTwoByteStringTag:
1997 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998 default:
1999 break;
2000 }
2001
2002 UNREACHABLE();
2003 return 0;
2004}
2005
2006
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002007void String::Set(int index, uint16_t value) {
2008 ASSERT(index >= 0 && index < length());
2009 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002010
ager@chromium.org5ec48922009-05-05 07:25:34 +00002011 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002012 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2013 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014}
2015
2016
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002017bool String::IsFlat() {
2018 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002019 case kConsStringTag: {
2020 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002021 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002022 return second->length() == 0;
2023 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002024 default:
2025 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026 }
2027}
2028
2029
ager@chromium.org7c537e22008-10-16 08:43:32 +00002030uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031 ASSERT(index >= 0 && index < length());
2032 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2033}
2034
2035
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2038 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2039 static_cast<byte>(value));
2040}
2041
2042
ager@chromium.org7c537e22008-10-16 08:43:32 +00002043Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044 return FIELD_ADDR(this, kHeaderSize);
2045}
2046
2047
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002048char* SeqAsciiString::GetChars() {
2049 return reinterpret_cast<char*>(GetCharsAddress());
2050}
2051
2052
ager@chromium.org7c537e22008-10-16 08:43:32 +00002053Address SeqTwoByteString::GetCharsAddress() {
2054 return FIELD_ADDR(this, kHeaderSize);
2055}
2056
2057
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002058uc16* SeqTwoByteString::GetChars() {
2059 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2060}
2061
2062
ager@chromium.org7c537e22008-10-16 08:43:32 +00002063uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064 ASSERT(index >= 0 && index < length());
2065 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2066}
2067
2068
ager@chromium.org7c537e22008-10-16 08:43:32 +00002069void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070 ASSERT(index >= 0 && index < length());
2071 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2072}
2073
2074
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002075int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002076 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077}
2078
2079
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002080int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002081 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002082}
2083
2084
ager@chromium.org870a0b62008-11-04 11:43:05 +00002085String* ConsString::first() {
2086 return String::cast(READ_FIELD(this, kFirstOffset));
2087}
2088
2089
2090Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091 return READ_FIELD(this, kFirstOffset);
2092}
2093
2094
ager@chromium.org870a0b62008-11-04 11:43:05 +00002095void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002097 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098}
2099
2100
ager@chromium.org870a0b62008-11-04 11:43:05 +00002101String* ConsString::second() {
2102 return String::cast(READ_FIELD(this, kSecondOffset));
2103}
2104
2105
2106Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 return READ_FIELD(this, kSecondOffset);
2108}
2109
2110
ager@chromium.org870a0b62008-11-04 11:43:05 +00002111void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002113 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114}
2115
2116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2118 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2119}
2120
2121
2122void ExternalAsciiString::set_resource(
2123 ExternalAsciiString::Resource* resource) {
2124 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2125}
2126
2127
2128ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2129 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2130}
2131
2132
2133void ExternalTwoByteString::set_resource(
2134 ExternalTwoByteString::Resource* resource) {
2135 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2136}
2137
2138
ager@chromium.orgac091b72010-05-05 07:34:42 +00002139void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002140 set_finger_index(kEntriesIndex);
2141 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002142}
2143
2144
2145void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002146 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002147 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002148 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002149 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002150 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002151 MakeZeroSize();
2152}
2153
2154
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002155int JSFunctionResultCache::size() {
2156 return Smi::cast(get(kCacheSizeIndex))->value();
2157}
2158
2159
2160void JSFunctionResultCache::set_size(int size) {
2161 set(kCacheSizeIndex, Smi::FromInt(size));
2162}
2163
2164
2165int JSFunctionResultCache::finger_index() {
2166 return Smi::cast(get(kFingerIndex))->value();
2167}
2168
2169
2170void JSFunctionResultCache::set_finger_index(int finger_index) {
2171 set(kFingerIndex, Smi::FromInt(finger_index));
2172}
2173
2174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175byte ByteArray::get(int index) {
2176 ASSERT(index >= 0 && index < this->length());
2177 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2178}
2179
2180
2181void ByteArray::set(int index, byte value) {
2182 ASSERT(index >= 0 && index < this->length());
2183 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2184}
2185
2186
2187int ByteArray::get_int(int index) {
2188 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2189 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2190}
2191
2192
2193ByteArray* ByteArray::FromDataStartAddress(Address address) {
2194 ASSERT_TAG_ALIGNED(address);
2195 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2196}
2197
2198
2199Address ByteArray::GetDataStartAddress() {
2200 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2201}
2202
2203
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002204uint8_t* ExternalPixelArray::external_pixel_pointer() {
2205 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002206}
2207
2208
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002209uint8_t ExternalPixelArray::get(int index) {
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 return ptr[index];
2213}
2214
2215
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002216void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002217 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002218 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002219 ptr[index] = value;
2220}
2221
2222
ager@chromium.org3811b432009-10-28 14:53:37 +00002223void* ExternalArray::external_pointer() {
2224 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2225 return reinterpret_cast<void*>(ptr);
2226}
2227
2228
2229void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2230 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2231 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2232}
2233
2234
2235int8_t ExternalByteArray::get(int index) {
2236 ASSERT((index >= 0) && (index < this->length()));
2237 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2238 return ptr[index];
2239}
2240
2241
2242void ExternalByteArray::set(int index, int8_t value) {
2243 ASSERT((index >= 0) && (index < this->length()));
2244 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2245 ptr[index] = value;
2246}
2247
2248
2249uint8_t ExternalUnsignedByteArray::get(int index) {
2250 ASSERT((index >= 0) && (index < this->length()));
2251 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2252 return ptr[index];
2253}
2254
2255
2256void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2257 ASSERT((index >= 0) && (index < this->length()));
2258 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2259 ptr[index] = value;
2260}
2261
2262
2263int16_t ExternalShortArray::get(int index) {
2264 ASSERT((index >= 0) && (index < this->length()));
2265 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2266 return ptr[index];
2267}
2268
2269
2270void ExternalShortArray::set(int index, int16_t value) {
2271 ASSERT((index >= 0) && (index < this->length()));
2272 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2273 ptr[index] = value;
2274}
2275
2276
2277uint16_t ExternalUnsignedShortArray::get(int index) {
2278 ASSERT((index >= 0) && (index < this->length()));
2279 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2280 return ptr[index];
2281}
2282
2283
2284void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2285 ASSERT((index >= 0) && (index < this->length()));
2286 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2287 ptr[index] = value;
2288}
2289
2290
2291int32_t ExternalIntArray::get(int index) {
2292 ASSERT((index >= 0) && (index < this->length()));
2293 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2294 return ptr[index];
2295}
2296
2297
2298void ExternalIntArray::set(int index, int32_t value) {
2299 ASSERT((index >= 0) && (index < this->length()));
2300 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2301 ptr[index] = value;
2302}
2303
2304
2305uint32_t ExternalUnsignedIntArray::get(int index) {
2306 ASSERT((index >= 0) && (index < this->length()));
2307 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2308 return ptr[index];
2309}
2310
2311
2312void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2313 ASSERT((index >= 0) && (index < this->length()));
2314 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2315 ptr[index] = value;
2316}
2317
2318
2319float ExternalFloatArray::get(int index) {
2320 ASSERT((index >= 0) && (index < this->length()));
2321 float* ptr = static_cast<float*>(external_pointer());
2322 return ptr[index];
2323}
2324
2325
2326void ExternalFloatArray::set(int index, float value) {
2327 ASSERT((index >= 0) && (index < this->length()));
2328 float* ptr = static_cast<float*>(external_pointer());
2329 ptr[index] = value;
2330}
2331
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002332
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002333double ExternalDoubleArray::get(int index) {
2334 ASSERT((index >= 0) && (index < this->length()));
2335 double* ptr = static_cast<double*>(external_pointer());
2336 return ptr[index];
2337}
2338
2339
2340void ExternalDoubleArray::set(int index, double value) {
2341 ASSERT((index >= 0) && (index < this->length()));
2342 double* ptr = static_cast<double*>(external_pointer());
2343 ptr[index] = value;
2344}
2345
2346
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002347int Map::visitor_id() {
2348 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2349}
2350
2351
2352void Map::set_visitor_id(int id) {
2353 ASSERT(0 <= id && id < 256);
2354 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2355}
2356
ager@chromium.org3811b432009-10-28 14:53:37 +00002357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002359 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2360}
2361
2362
2363int Map::inobject_properties() {
2364 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365}
2366
2367
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002368int Map::pre_allocated_property_fields() {
2369 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2370}
2371
2372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002374 int instance_size = map->instance_size();
2375 if (instance_size != kVariableSizeSentinel) return instance_size;
2376 // We can ignore the "symbol" bit becase it is only set for symbols
2377 // and implies a string type.
2378 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002379 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002381 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002382 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002383 if (instance_type == ASCII_STRING_TYPE) {
2384 return SeqAsciiString::SizeFor(
2385 reinterpret_cast<SeqAsciiString*>(this)->length());
2386 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002387 if (instance_type == BYTE_ARRAY_TYPE) {
2388 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2389 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002390 if (instance_type == STRING_TYPE) {
2391 return SeqTwoByteString::SizeFor(
2392 reinterpret_cast<SeqTwoByteString*>(this)->length());
2393 }
2394 ASSERT(instance_type == CODE_TYPE);
2395 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396}
2397
2398
2399void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002400 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002401 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402 ASSERT(0 <= value && value < 256);
2403 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2404}
2405
2406
ager@chromium.org7c537e22008-10-16 08:43:32 +00002407void Map::set_inobject_properties(int value) {
2408 ASSERT(0 <= value && value < 256);
2409 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2410}
2411
2412
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002413void Map::set_pre_allocated_property_fields(int value) {
2414 ASSERT(0 <= value && value < 256);
2415 WRITE_BYTE_FIELD(this,
2416 kPreAllocatedPropertyFieldsOffset,
2417 static_cast<byte>(value));
2418}
2419
2420
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421InstanceType Map::instance_type() {
2422 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2423}
2424
2425
2426void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2428}
2429
2430
2431int Map::unused_property_fields() {
2432 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2433}
2434
2435
2436void Map::set_unused_property_fields(int value) {
2437 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2438}
2439
2440
2441byte Map::bit_field() {
2442 return READ_BYTE_FIELD(this, kBitFieldOffset);
2443}
2444
2445
2446void Map::set_bit_field(byte value) {
2447 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2448}
2449
2450
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002451byte Map::bit_field2() {
2452 return READ_BYTE_FIELD(this, kBitField2Offset);
2453}
2454
2455
2456void Map::set_bit_field2(byte value) {
2457 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2458}
2459
2460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461void Map::set_non_instance_prototype(bool value) {
2462 if (value) {
2463 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2464 } else {
2465 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2466 }
2467}
2468
2469
2470bool Map::has_non_instance_prototype() {
2471 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2472}
2473
2474
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002475void Map::set_function_with_prototype(bool value) {
2476 if (value) {
2477 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2478 } else {
2479 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2480 }
2481}
2482
2483
2484bool Map::function_with_prototype() {
2485 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2486}
2487
2488
ager@chromium.org870a0b62008-11-04 11:43:05 +00002489void Map::set_is_access_check_needed(bool access_check_needed) {
2490 if (access_check_needed) {
2491 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2492 } else {
2493 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2494 }
2495}
2496
2497
2498bool Map::is_access_check_needed() {
2499 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2500}
2501
2502
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002503void Map::set_is_extensible(bool value) {
2504 if (value) {
2505 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2506 } else {
2507 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2508 }
2509}
2510
2511bool Map::is_extensible() {
2512 return ((1 << kIsExtensible) & bit_field2()) != 0;
2513}
2514
2515
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002516void Map::set_attached_to_shared_function_info(bool value) {
2517 if (value) {
2518 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2519 } else {
2520 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2521 }
2522}
2523
2524bool Map::attached_to_shared_function_info() {
2525 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2526}
2527
2528
2529void Map::set_is_shared(bool value) {
2530 if (value) {
2531 set_bit_field2(bit_field2() | (1 << kIsShared));
2532 } else {
2533 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2534 }
2535}
2536
2537bool Map::is_shared() {
2538 return ((1 << kIsShared) & bit_field2()) != 0;
2539}
2540
2541
2542JSFunction* Map::unchecked_constructor() {
2543 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2544}
2545
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002546
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002547FixedArray* Map::unchecked_prototype_transitions() {
2548 return reinterpret_cast<FixedArray*>(
2549 READ_FIELD(this, kPrototypeTransitionsOffset));
2550}
2551
2552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002553Code::Flags Code::flags() {
2554 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2555}
2556
2557
2558void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002559 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002560 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002561 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2562 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002563 ExtractArgumentsCountFromFlags(flags) >= 0);
2564 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2565}
2566
2567
2568Code::Kind Code::kind() {
2569 return ExtractKindFromFlags(flags());
2570}
2571
2572
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002573InLoopFlag Code::ic_in_loop() {
2574 return ExtractICInLoopFromFlags(flags());
2575}
2576
2577
kasper.lund7276f142008-07-30 08:49:36 +00002578InlineCacheState Code::ic_state() {
2579 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580 // Only allow uninitialized or debugger states for non-IC code
2581 // objects. This is used in the debugger to determine whether or not
2582 // a call to code object has been replaced with a debug break call.
2583 ASSERT(is_inline_cache_stub() ||
2584 result == UNINITIALIZED ||
2585 result == DEBUG_BREAK ||
2586 result == DEBUG_PREPARE_STEP_IN);
2587 return result;
2588}
2589
2590
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002591Code::ExtraICState Code::extra_ic_state() {
2592 ASSERT(is_inline_cache_stub());
2593 return ExtractExtraICStateFromFlags(flags());
2594}
2595
2596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002598 return ExtractTypeFromFlags(flags());
2599}
2600
2601
2602int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002603 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002604 return ExtractArgumentsCountFromFlags(flags());
2605}
2606
2607
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002608int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002609 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2611 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002612 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002613}
2614
2615
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002616void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002617 ASSERT(kind() == STUB ||
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002618 kind() == TYPE_RECORDING_UNARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002619 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2620 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002621 ASSERT(0 <= major && major < 256);
2622 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623}
2624
2625
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002626bool Code::optimizable() {
2627 ASSERT(kind() == FUNCTION);
2628 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2629}
2630
2631
2632void Code::set_optimizable(bool value) {
2633 ASSERT(kind() == FUNCTION);
2634 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2635}
2636
2637
2638bool Code::has_deoptimization_support() {
2639 ASSERT(kind() == FUNCTION);
2640 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2641}
2642
2643
2644void Code::set_has_deoptimization_support(bool value) {
2645 ASSERT(kind() == FUNCTION);
2646 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2647}
2648
2649
2650int Code::allow_osr_at_loop_nesting_level() {
2651 ASSERT(kind() == FUNCTION);
2652 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2653}
2654
2655
2656void Code::set_allow_osr_at_loop_nesting_level(int level) {
2657 ASSERT(kind() == FUNCTION);
2658 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2659 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2660}
2661
2662
2663unsigned Code::stack_slots() {
2664 ASSERT(kind() == OPTIMIZED_FUNCTION);
2665 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2666}
2667
2668
2669void Code::set_stack_slots(unsigned slots) {
2670 ASSERT(kind() == OPTIMIZED_FUNCTION);
2671 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2672}
2673
2674
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002675unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002677 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678}
2679
2680
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002681void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002682 ASSERT(kind() == OPTIMIZED_FUNCTION);
2683 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002684 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002685}
2686
2687
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002688unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002690 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691}
2692
2693
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002694void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002695 ASSERT(kind() == FUNCTION);
2696 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002697 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698}
2699
2700
2701CheckType Code::check_type() {
2702 ASSERT(is_call_stub() || is_keyed_call_stub());
2703 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2704 return static_cast<CheckType>(type);
2705}
2706
2707
2708void Code::set_check_type(CheckType value) {
2709 ASSERT(is_call_stub() || is_keyed_call_stub());
2710 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2711}
2712
2713
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002714ExternalArrayType Code::external_array_type() {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002715 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002716 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2717 return static_cast<ExternalArrayType>(type);
2718}
2719
2720
2721void Code::set_external_array_type(ExternalArrayType value) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002722 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002723 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2724}
2725
2726
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002727byte Code::type_recording_unary_op_type() {
2728 ASSERT(is_type_recording_unary_op_stub());
2729 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2730}
2731
2732
2733void Code::set_type_recording_unary_op_type(byte value) {
2734 ASSERT(is_type_recording_unary_op_stub());
2735 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2736}
2737
2738
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739byte Code::type_recording_binary_op_type() {
2740 ASSERT(is_type_recording_binary_op_stub());
2741 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2742}
2743
2744
2745void Code::set_type_recording_binary_op_type(byte value) {
2746 ASSERT(is_type_recording_binary_op_stub());
2747 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2748}
2749
2750
2751byte Code::type_recording_binary_op_result_type() {
2752 ASSERT(is_type_recording_binary_op_stub());
2753 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2754}
2755
2756
2757void Code::set_type_recording_binary_op_result_type(byte value) {
2758 ASSERT(is_type_recording_binary_op_stub());
2759 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2760}
2761
2762
2763byte Code::compare_state() {
2764 ASSERT(is_compare_ic_stub());
2765 return READ_BYTE_FIELD(this, kCompareStateOffset);
2766}
2767
2768
2769void Code::set_compare_state(byte value) {
2770 ASSERT(is_compare_ic_stub());
2771 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2772}
2773
2774
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002775bool Code::is_inline_cache_stub() {
2776 Kind kind = this->kind();
2777 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2778}
2779
2780
2781Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002782 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002783 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002784 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002786 int argc,
2787 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002788 // Extra IC state is only allowed for monomorphic call IC stubs
2789 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002790 ASSERT(extra_ic_state == kNoExtraICState ||
2791 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002792 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002793 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002794 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795 // Compute the bit mask.
2796 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002797 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002798 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002799 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002800 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002801 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002802 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803 // Cast to flags and validate result before returning it.
2804 Flags result = static_cast<Flags>(bits);
2805 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002806 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002807 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002808 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002809 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2811 return result;
2812}
2813
2814
2815Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2816 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002817 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002818 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002819 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002821 return ComputeFlags(
2822 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002823}
2824
2825
2826Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2827 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2828 return static_cast<Kind>(bits);
2829}
2830
2831
kasper.lund7276f142008-07-30 08:49:36 +00002832InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2833 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834 return static_cast<InlineCacheState>(bits);
2835}
2836
2837
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002838Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2839 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2840 return static_cast<ExtraICState>(bits);
2841}
2842
2843
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002844InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2845 int bits = (flags & kFlagsICInLoopMask);
2846 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2847}
2848
2849
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002850PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2851 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2852 return static_cast<PropertyType>(bits);
2853}
2854
2855
2856int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2857 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2858}
2859
2860
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002861InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2862 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2863 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2864}
2865
2866
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002867Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2868 int bits = flags & ~kFlagsTypeMask;
2869 return static_cast<Flags>(bits);
2870}
2871
2872
ager@chromium.org8bb60582008-12-11 12:02:20 +00002873Code* Code::GetCodeFromTargetAddress(Address address) {
2874 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2875 // GetCodeFromTargetAddress might be called when marking objects during mark
2876 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2877 // Code::cast. Code::cast does not work when the object's map is
2878 // marked.
2879 Code* result = reinterpret_cast<Code*>(code);
2880 return result;
2881}
2882
2883
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002884Isolate* Map::isolate() {
2885 return heap()->isolate();
2886}
2887
2888
2889Heap* Map::heap() {
2890 // NOTE: address() helper is not used to save one instruction.
2891 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2892 ASSERT(heap != NULL);
2893 ASSERT(heap->isolate() == Isolate::Current());
2894 return heap;
2895}
2896
2897
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002898Heap* Code::heap() {
2899 // NOTE: address() helper is not used to save one instruction.
2900 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2901 ASSERT(heap != NULL);
2902 ASSERT(heap->isolate() == Isolate::Current());
2903 return heap;
2904}
2905
2906
2907Isolate* Code::isolate() {
2908 return heap()->isolate();
2909}
2910
2911
2912Heap* JSGlobalPropertyCell::heap() {
2913 // NOTE: address() helper is not used to save one instruction.
2914 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2915 ASSERT(heap != NULL);
2916 ASSERT(heap->isolate() == Isolate::Current());
2917 return heap;
2918}
2919
2920
2921Isolate* JSGlobalPropertyCell::isolate() {
2922 return heap()->isolate();
2923}
2924
2925
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002926Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2927 return HeapObject::
2928 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2929}
2930
2931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932Object* Map::prototype() {
2933 return READ_FIELD(this, kPrototypeOffset);
2934}
2935
2936
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002937void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938 ASSERT(value->IsNull() || value->IsJSObject());
2939 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002940 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002941}
2942
2943
lrn@chromium.org303ada72010-10-27 09:33:13 +00002944MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002945 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002946 Object* obj;
2947 { MaybeObject* maybe_obj = CopyDropTransitions();
2948 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2949 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002950 Map* new_map = Map::cast(obj);
2951 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002952 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002953 return new_map;
2954}
2955
2956
lrn@chromium.org303ada72010-10-27 09:33:13 +00002957MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002958 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002959 Object* obj;
2960 { MaybeObject* maybe_obj = CopyDropTransitions();
2961 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2962 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002963 Map* new_map = Map::cast(obj);
2964 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002965 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002966 return new_map;
2967}
2968
2969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970ACCESSORS(Map, instance_descriptors, DescriptorArray,
2971 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002972ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002973ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002974ACCESSORS(Map, constructor, Object, kConstructorOffset)
2975
2976ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2977ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002978ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
2979 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002980
2981ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2982ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002983ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002985ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986
2987ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2988ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2989ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2990ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2991ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2992
2993ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2994ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2995ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2996
2997ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2998ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2999ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3000ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3001ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3002ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3003
3004ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3005ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3006
3007ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3008ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3009
3010ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3011ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003012ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3013 kPropertyAccessorsOffset)
3014ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3015 kPrototypeTemplateOffset)
3016ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3017ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3018 kNamedPropertyHandlerOffset)
3019ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3020 kIndexedPropertyHandlerOffset)
3021ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3022 kInstanceTemplateOffset)
3023ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3024ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3026 kInstanceCallHandlerOffset)
3027ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3028 kAccessCheckInfoOffset)
3029ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3030
3031ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003032ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3033 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034
3035ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3036ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3037
3038ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3039
3040ACCESSORS(Script, source, Object, kSourceOffset)
3041ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003042ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3044ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003045ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003046ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003047ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003048ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003049ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003050ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003051ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003052ACCESSORS(Script, eval_from_instructions_offset, Smi,
3053 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003054
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003055#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003056ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3057ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3058ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3059ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3060
3061ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3062ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3063ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3064ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003065#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003066
3067ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003068ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3069ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3071 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003072ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003073ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3074ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003075ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003076ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3077 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003078
3079BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3080 kHiddenPrototypeBit)
3081BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3082BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3083 kNeedsAccessCheckBit)
3084BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3085 kIsExpressionBit)
3086BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3087 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003088BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003089 has_only_simple_this_property_assignments,
3090 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003091BOOL_ACCESSORS(SharedFunctionInfo,
3092 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003093 allows_lazy_compilation,
3094 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003095
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003096
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003097#if V8_HOST_ARCH_32_BIT
3098SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3099SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003100 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003101SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003103SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3104SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003105 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003106SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3107SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003108 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003109SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003110 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003111SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003112 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003114#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003115
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003116#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003117 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003118 int holder::name() { \
3119 int value = READ_INT_FIELD(this, offset); \
3120 ASSERT(kHeapObjectTag == 1); \
3121 ASSERT((value & kHeapObjectTag) == 0); \
3122 return value >> 1; \
3123 } \
3124 void holder::set_##name(int value) { \
3125 ASSERT(kHeapObjectTag == 1); \
3126 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3127 (value & 0xC0000000) == 0x000000000); \
3128 WRITE_INT_FIELD(this, \
3129 offset, \
3130 (value << 1) & ~kHeapObjectTag); \
3131 }
3132
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003133#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3134 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003135 INT_ACCESSORS(holder, name, offset)
3136
3137
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003138PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003139PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3140 formal_parameter_count,
3141 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003142
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003143PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3144 expected_nof_properties,
3145 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003146PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3147
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003148PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3149PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3150 start_position_and_type,
3151 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003152
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003153PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3154 function_token_position,
3155 kFunctionTokenPositionOffset)
3156PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3157 compiler_hints,
3158 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003159
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003160PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3161 this_property_assignments_count,
3162 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003163PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003164#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003165
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003166
3167int SharedFunctionInfo::construction_count() {
3168 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3169}
3170
3171
3172void SharedFunctionInfo::set_construction_count(int value) {
3173 ASSERT(0 <= value && value < 256);
3174 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3175}
3176
3177
3178bool SharedFunctionInfo::live_objects_may_exist() {
3179 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3180}
3181
3182
3183void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3184 if (value) {
3185 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3186 } else {
3187 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3188 }
3189}
3190
3191
3192bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003193 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003194}
3195
3196
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197bool SharedFunctionInfo::optimization_disabled() {
3198 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3199}
3200
3201
3202void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3203 set_compiler_hints(BooleanBit::set(compiler_hints(),
3204 kOptimizationDisabled,
3205 disable));
3206 // If disabling optimizations we reflect that in the code object so
3207 // it will not be counted as optimizable code.
3208 if ((code()->kind() == Code::FUNCTION) && disable) {
3209 code()->set_optimizable(false);
3210 }
3211}
3212
3213
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003214bool SharedFunctionInfo::strict_mode() {
3215 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3216}
3217
3218
3219void SharedFunctionInfo::set_strict_mode(bool value) {
3220 set_compiler_hints(BooleanBit::set(compiler_hints(),
3221 kStrictModeFunction,
3222 value));
3223}
3224
3225
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003226bool SharedFunctionInfo::es5_native() {
3227 return BooleanBit::get(compiler_hints(), kES5Native);
3228}
3229
3230
3231void SharedFunctionInfo::set_es5_native(bool value) {
3232 set_compiler_hints(BooleanBit::set(compiler_hints(),
3233 kES5Native,
3234 value));
3235}
3236
3237
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003238ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3239ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3240
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003241bool Script::HasValidSource() {
3242 Object* src = this->source();
3243 if (!src->IsString()) return true;
3244 String* src_str = String::cast(src);
3245 if (!StringShape(src_str).IsExternal()) return true;
3246 if (src_str->IsAsciiRepresentation()) {
3247 return ExternalAsciiString::cast(src)->resource() != NULL;
3248 } else if (src_str->IsTwoByteRepresentation()) {
3249 return ExternalTwoByteString::cast(src)->resource() != NULL;
3250 }
3251 return true;
3252}
3253
3254
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003255void SharedFunctionInfo::DontAdaptArguments() {
3256 ASSERT(code()->kind() == Code::BUILTIN);
3257 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3258}
3259
3260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261int SharedFunctionInfo::start_position() {
3262 return start_position_and_type() >> kStartPositionShift;
3263}
3264
3265
3266void SharedFunctionInfo::set_start_position(int start_position) {
3267 set_start_position_and_type((start_position << kStartPositionShift)
3268 | (start_position_and_type() & ~kStartPositionMask));
3269}
3270
3271
3272Code* SharedFunctionInfo::code() {
3273 return Code::cast(READ_FIELD(this, kCodeOffset));
3274}
3275
3276
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003277Code* SharedFunctionInfo::unchecked_code() {
3278 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3279}
3280
3281
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003282void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003284 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285}
3286
3287
ager@chromium.orgb5737492010-07-15 09:29:43 +00003288SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3289 return reinterpret_cast<SerializedScopeInfo*>(
3290 READ_FIELD(this, kScopeInfoOffset));
3291}
3292
3293
3294void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3295 WriteBarrierMode mode) {
3296 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003297 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003298}
3299
3300
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301Smi* SharedFunctionInfo::deopt_counter() {
3302 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3303}
3304
3305
3306void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3307 WRITE_FIELD(this, kDeoptCounterOffset, value);
3308}
3309
3310
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003312 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003313 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314}
3315
3316
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003317bool SharedFunctionInfo::IsApiFunction() {
3318 return function_data()->IsFunctionTemplateInfo();
3319}
3320
3321
3322FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3323 ASSERT(IsApiFunction());
3324 return FunctionTemplateInfo::cast(function_data());
3325}
3326
3327
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003328bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003329 return function_data()->IsSmi();
3330}
3331
3332
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003333BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3334 ASSERT(HasBuiltinFunctionId());
3335 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003336}
3337
3338
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003339int SharedFunctionInfo::code_age() {
3340 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3341}
3342
3343
3344void SharedFunctionInfo::set_code_age(int code_age) {
3345 set_compiler_hints(compiler_hints() |
3346 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3347}
3348
3349
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003350bool SharedFunctionInfo::has_deoptimization_support() {
3351 Code* code = this->code();
3352 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3353}
3354
3355
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003356bool JSFunction::IsBuiltin() {
3357 return context()->global()->IsJSBuiltinsObject();
3358}
3359
3360
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003361bool JSFunction::NeedsArgumentsAdaption() {
3362 return shared()->formal_parameter_count() !=
3363 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3364}
3365
3366
3367bool JSFunction::IsOptimized() {
3368 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3369}
3370
3371
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003372bool JSFunction::IsOptimizable() {
3373 return code()->kind() == Code::FUNCTION && code()->optimizable();
3374}
3375
3376
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003377bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003378 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379}
3380
3381
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003383 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003384}
3385
3386
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003387Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003388 return reinterpret_cast<Code*>(
3389 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003390}
3391
3392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003393void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003394 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003395 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003396 Address entry = value->entry();
3397 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003398}
3399
3400
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401void JSFunction::ReplaceCode(Code* code) {
3402 bool was_optimized = IsOptimized();
3403 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3404
3405 set_code(code);
3406
3407 // Add/remove the function from the list of optimized functions for this
3408 // context based on the state change.
3409 if (!was_optimized && is_optimized) {
3410 context()->global_context()->AddOptimizedFunction(this);
3411 }
3412 if (was_optimized && !is_optimized) {
3413 context()->global_context()->RemoveOptimizedFunction(this);
3414 }
3415}
3416
3417
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418Context* JSFunction::context() {
3419 return Context::cast(READ_FIELD(this, kContextOffset));
3420}
3421
3422
3423Object* JSFunction::unchecked_context() {
3424 return READ_FIELD(this, kContextOffset);
3425}
3426
3427
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003428SharedFunctionInfo* JSFunction::unchecked_shared() {
3429 return reinterpret_cast<SharedFunctionInfo*>(
3430 READ_FIELD(this, kSharedFunctionInfoOffset));
3431}
3432
3433
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003434void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003435 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003436 WRITE_FIELD(this, kContextOffset, value);
3437 WRITE_BARRIER(this, kContextOffset);
3438}
3439
3440ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3441 kPrototypeOrInitialMapOffset)
3442
3443
3444Map* JSFunction::initial_map() {
3445 return Map::cast(prototype_or_initial_map());
3446}
3447
3448
3449void JSFunction::set_initial_map(Map* value) {
3450 set_prototype_or_initial_map(value);
3451}
3452
3453
3454bool JSFunction::has_initial_map() {
3455 return prototype_or_initial_map()->IsMap();
3456}
3457
3458
3459bool JSFunction::has_instance_prototype() {
3460 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3461}
3462
3463
3464bool JSFunction::has_prototype() {
3465 return map()->has_non_instance_prototype() || has_instance_prototype();
3466}
3467
3468
3469Object* JSFunction::instance_prototype() {
3470 ASSERT(has_instance_prototype());
3471 if (has_initial_map()) return initial_map()->prototype();
3472 // When there is no initial map and the prototype is a JSObject, the
3473 // initial map field is used for the prototype field.
3474 return prototype_or_initial_map();
3475}
3476
3477
3478Object* JSFunction::prototype() {
3479 ASSERT(has_prototype());
3480 // If the function's prototype property has been set to a non-JSObject
3481 // value, that value is stored in the constructor field of the map.
3482 if (map()->has_non_instance_prototype()) return map()->constructor();
3483 return instance_prototype();
3484}
3485
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003486bool JSFunction::should_have_prototype() {
3487 return map()->function_with_prototype();
3488}
3489
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490
3491bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003492 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493}
3494
3495
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003496int JSFunction::NumberOfLiterals() {
3497 return literals()->length();
3498}
3499
3500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003502 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003503 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003504}
3505
3506
3507void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3508 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003509 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003510 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3511 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3512}
3513
3514
3515Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003516 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003517 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3518}
3519
3520
3521void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3522 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003523 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003524 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003525 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003526}
3527
3528
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003529ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3530
3531
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003532Address Foreign::address() {
3533 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534}
3535
3536
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003537void Foreign::set_address(Address value) {
3538 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003539}
3540
3541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542ACCESSORS(JSValue, value, Object, kValueOffset)
3543
3544
3545JSValue* JSValue::cast(Object* obj) {
3546 ASSERT(obj->IsJSValue());
3547 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3548 return reinterpret_cast<JSValue*>(obj);
3549}
3550
3551
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003552ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3553ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3554ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3555ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3556ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3557SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3558SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3559
3560
3561JSMessageObject* JSMessageObject::cast(Object* obj) {
3562 ASSERT(obj->IsJSMessageObject());
3563 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3564 return reinterpret_cast<JSMessageObject*>(obj);
3565}
3566
3567
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003568INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003569ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003570ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003571ACCESSORS(Code, next_code_flushing_candidate,
3572 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003573
3574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575byte* Code::instruction_start() {
3576 return FIELD_ADDR(this, kHeaderSize);
3577}
3578
3579
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003580byte* Code::instruction_end() {
3581 return instruction_start() + instruction_size();
3582}
3583
3584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003585int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003586 return RoundUp(instruction_size(), kObjectAlignment);
3587}
3588
3589
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003590FixedArray* Code::unchecked_deoptimization_data() {
3591 return reinterpret_cast<FixedArray*>(
3592 READ_FIELD(this, kDeoptimizationDataOffset));
3593}
3594
3595
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003596ByteArray* Code::unchecked_relocation_info() {
3597 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598}
3599
3600
3601byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003602 return unchecked_relocation_info()->GetDataStartAddress();
3603}
3604
3605
3606int Code::relocation_size() {
3607 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608}
3609
3610
3611byte* Code::entry() {
3612 return instruction_start();
3613}
3614
3615
3616bool Code::contains(byte* pc) {
3617 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003618 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003619}
3620
3621
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003622ACCESSORS(JSArray, length, Object, kLengthOffset)
3623
3624
ager@chromium.org236ad962008-09-25 09:45:57 +00003625ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003626
3627
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003628JSRegExp::Type JSRegExp::TypeTag() {
3629 Object* data = this->data();
3630 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3631 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3632 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003633}
3634
3635
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003636int JSRegExp::CaptureCount() {
3637 switch (TypeTag()) {
3638 case ATOM:
3639 return 0;
3640 case IRREGEXP:
3641 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3642 default:
3643 UNREACHABLE();
3644 return -1;
3645 }
3646}
3647
3648
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003649JSRegExp::Flags JSRegExp::GetFlags() {
3650 ASSERT(this->data()->IsFixedArray());
3651 Object* data = this->data();
3652 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3653 return Flags(smi->value());
3654}
3655
3656
3657String* JSRegExp::Pattern() {
3658 ASSERT(this->data()->IsFixedArray());
3659 Object* data = this->data();
3660 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3661 return pattern;
3662}
3663
3664
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003665Object* JSRegExp::DataAt(int index) {
3666 ASSERT(TypeTag() != NOT_COMPILED);
3667 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003668}
3669
3670
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003671void JSRegExp::SetDataAt(int index, Object* value) {
3672 ASSERT(TypeTag() != NOT_COMPILED);
3673 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3674 FixedArray::cast(data())->set(index, value);
3675}
3676
3677
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003678JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003679 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003680 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3681 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003682 return FAST_ELEMENTS;
3683 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003684 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003685 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003686 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3687 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003688 ASSERT(array->IsDictionary());
3689 return DICTIONARY_ELEMENTS;
3690 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003691 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003692 if (array->IsExternalArray()) {
3693 switch (array->map()->instance_type()) {
3694 case EXTERNAL_BYTE_ARRAY_TYPE:
3695 return EXTERNAL_BYTE_ELEMENTS;
3696 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3697 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3698 case EXTERNAL_SHORT_ARRAY_TYPE:
3699 return EXTERNAL_SHORT_ELEMENTS;
3700 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3701 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3702 case EXTERNAL_INT_ARRAY_TYPE:
3703 return EXTERNAL_INT_ELEMENTS;
3704 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3705 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003706 case EXTERNAL_FLOAT_ARRAY_TYPE:
3707 return EXTERNAL_FLOAT_ELEMENTS;
3708 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3709 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003710 case EXTERNAL_PIXEL_ARRAY_TYPE:
3711 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003712 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003713 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003714 }
3715 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003716 UNREACHABLE();
3717 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003718}
3719
3720
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003721bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003722 return GetElementsKind() == FAST_ELEMENTS;
3723}
3724
3725
3726bool JSObject::HasDictionaryElements() {
3727 return GetElementsKind() == DICTIONARY_ELEMENTS;
3728}
3729
3730
ager@chromium.org3811b432009-10-28 14:53:37 +00003731bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003732 HeapObject* array = elements();
3733 ASSERT(array != NULL);
3734 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003735}
3736
3737
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003738#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3739bool JSObject::HasExternal##name##Elements() { \
3740 HeapObject* array = elements(); \
3741 ASSERT(array != NULL); \
3742 if (!array->IsHeapObject()) \
3743 return false; \
3744 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003745}
3746
3747
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003748EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3749EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3750EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3751EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3752 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3753EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3754EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3755 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3756EXTERNAL_ELEMENTS_CHECK(Float,
3757 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003758EXTERNAL_ELEMENTS_CHECK(Double,
3759 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003760EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003761
3762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763bool JSObject::HasNamedInterceptor() {
3764 return map()->has_named_interceptor();
3765}
3766
3767
3768bool JSObject::HasIndexedInterceptor() {
3769 return map()->has_indexed_interceptor();
3770}
3771
3772
ager@chromium.org5c838252010-02-19 08:53:10 +00003773bool JSObject::AllowsSetElementsLength() {
3774 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003775 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003776 return result;
3777}
3778
3779
lrn@chromium.org303ada72010-10-27 09:33:13 +00003780MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003781 ASSERT(HasFastElements());
3782 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003783 Isolate* isolate = GetIsolate();
3784 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003785 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003786 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3787 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003788 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3789 return maybe_writable_elems;
3790 }
3791 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003792 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003793 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003794 return writable_elems;
3795}
3796
3797
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003798StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003799 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003800 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003801}
3802
3803
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003804NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003805 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003806 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807}
3808
3809
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003810bool String::IsHashFieldComputed(uint32_t field) {
3811 return (field & kHashNotComputedMask) == 0;
3812}
3813
3814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003816 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817}
3818
3819
3820uint32_t String::Hash() {
3821 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003822 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003823 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003824 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003825 return ComputeAndSetHash();
3826}
3827
3828
ager@chromium.org7c537e22008-10-16 08:43:32 +00003829StringHasher::StringHasher(int length)
3830 : length_(length),
3831 raw_running_hash_(0),
3832 array_index_(0),
3833 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3834 is_first_char_(true),
3835 is_valid_(true) { }
3836
3837
3838bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003839 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003840}
3841
3842
3843void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003844 // Use the Jenkins one-at-a-time hash function to update the hash
3845 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003846 raw_running_hash_ += c;
3847 raw_running_hash_ += (raw_running_hash_ << 10);
3848 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003849 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003850 if (is_array_index_) {
3851 if (c < '0' || c > '9') {
3852 is_array_index_ = false;
3853 } else {
3854 int d = c - '0';
3855 if (is_first_char_) {
3856 is_first_char_ = false;
3857 if (c == '0' && length_ > 1) {
3858 is_array_index_ = false;
3859 return;
3860 }
3861 }
3862 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3863 is_array_index_ = false;
3864 } else {
3865 array_index_ = array_index_ * 10 + d;
3866 }
3867 }
3868 }
3869}
3870
3871
3872void StringHasher::AddCharacterNoIndex(uc32 c) {
3873 ASSERT(!is_array_index());
3874 raw_running_hash_ += c;
3875 raw_running_hash_ += (raw_running_hash_ << 10);
3876 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3877}
3878
3879
3880uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003881 // Get the calculated raw hash value and do some more bit ops to distribute
3882 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003883 uint32_t result = raw_running_hash_;
3884 result += (result << 3);
3885 result ^= (result >> 11);
3886 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003887 if (result == 0) {
3888 result = 27;
3889 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003890 return result;
3891}
3892
3893
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003894template <typename schar>
3895uint32_t HashSequentialString(const schar* chars, int length) {
3896 StringHasher hasher(length);
3897 if (!hasher.has_trivial_hash()) {
3898 int i;
3899 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3900 hasher.AddCharacter(chars[i]);
3901 }
3902 for (; i < length; i++) {
3903 hasher.AddCharacterNoIndex(chars[i]);
3904 }
3905 }
3906 return hasher.GetHashField();
3907}
3908
3909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003910bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003911 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003912 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3913 return false;
3914 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003915 return SlowAsArrayIndex(index);
3916}
3917
3918
3919Object* JSObject::GetPrototype() {
3920 return JSObject::cast(this)->map()->prototype();
3921}
3922
3923
3924PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3925 return GetPropertyAttributeWithReceiver(this, key);
3926}
3927
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003928// TODO(504): this may be useful in other places too where JSGlobalProxy
3929// is used.
3930Object* JSObject::BypassGlobalProxy() {
3931 if (IsJSGlobalProxy()) {
3932 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003933 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003934 ASSERT(proto->IsJSGlobalObject());
3935 return proto;
3936 }
3937 return this;
3938}
3939
3940
3941bool JSObject::HasHiddenPropertiesObject() {
3942 ASSERT(!IsJSGlobalProxy());
3943 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003944 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003945 false) != ABSENT;
3946}
3947
3948
3949Object* JSObject::GetHiddenPropertiesObject() {
3950 ASSERT(!IsJSGlobalProxy());
3951 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003952 // You can't install a getter on a property indexed by the hidden symbol,
3953 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3954 // object.
3955 Object* result =
3956 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003957 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00003958 &attributes)->ToObjectUnchecked();
3959 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003960}
3961
3962
lrn@chromium.org303ada72010-10-27 09:33:13 +00003963MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003964 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003965 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003966 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003967 DONT_ENUM,
3968 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003969}
3970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971
3972bool JSObject::HasElement(uint32_t index) {
3973 return HasElementWithReceiver(this, index);
3974}
3975
3976
3977bool AccessorInfo::all_can_read() {
3978 return BooleanBit::get(flag(), kAllCanReadBit);
3979}
3980
3981
3982void AccessorInfo::set_all_can_read(bool value) {
3983 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3984}
3985
3986
3987bool AccessorInfo::all_can_write() {
3988 return BooleanBit::get(flag(), kAllCanWriteBit);
3989}
3990
3991
3992void AccessorInfo::set_all_can_write(bool value) {
3993 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3994}
3995
3996
ager@chromium.org870a0b62008-11-04 11:43:05 +00003997bool AccessorInfo::prohibits_overwriting() {
3998 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3999}
4000
4001
4002void AccessorInfo::set_prohibits_overwriting(bool value) {
4003 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4004}
4005
4006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004007PropertyAttributes AccessorInfo::property_attributes() {
4008 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4009}
4010
4011
4012void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4013 ASSERT(AttributesField::is_valid(attributes));
4014 int rest_value = flag()->value() & ~AttributesField::mask();
4015 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4016}
4017
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004018
4019template<typename Shape, typename Key>
4020void Dictionary<Shape, Key>::SetEntry(int entry,
4021 Object* key,
4022 Object* value) {
4023 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4024}
4025
4026
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004027template<typename Shape, typename Key>
4028void Dictionary<Shape, Key>::SetEntry(int entry,
4029 Object* key,
4030 Object* value,
4031 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004032 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004033 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004034 AssertNoAllocation no_gc;
4035 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004036 FixedArray::set(index, key, mode);
4037 FixedArray::set(index+1, value, mode);
4038 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004039}
4040
4041
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004042bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4043 ASSERT(other->IsNumber());
4044 return key == static_cast<uint32_t>(other->Number());
4045}
4046
4047
4048uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4049 return ComputeIntegerHash(key);
4050}
4051
4052
4053uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4054 ASSERT(other->IsNumber());
4055 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4056}
4057
4058
4059MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4060 return Isolate::Current()->heap()->NumberFromUint32(key);
4061}
4062
4063
4064bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4065 // We know that all entries in a hash table had their hash keys created.
4066 // Use that knowledge to have fast failure.
4067 if (key->Hash() != String::cast(other)->Hash()) return false;
4068 return key->Equals(String::cast(other));
4069}
4070
4071
4072uint32_t StringDictionaryShape::Hash(String* key) {
4073 return key->Hash();
4074}
4075
4076
4077uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4078 return String::cast(other)->Hash();
4079}
4080
4081
4082MaybeObject* StringDictionaryShape::AsObject(String* key) {
4083 return key;
4084}
4085
4086
4087void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004088 // No write barrier is needed since empty_fixed_array is not in new space.
4089 // Please note this function is used during marking:
4090 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004091 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4092 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004093}
4094
4095
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004096void JSArray::EnsureSize(int required_size) {
4097 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004098 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004099 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4100 if (elts->length() < required_size) {
4101 // Doubling in size would be overkill, but leave some slack to avoid
4102 // constantly growing.
4103 Expand(required_size + (required_size >> 3));
4104 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004105 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004106 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4107 // Expand will allocate a new backing store in new space even if the size
4108 // we asked for isn't larger than what we had before.
4109 Expand(required_size);
4110 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004111}
4112
4113
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004114void JSArray::set_length(Smi* length) {
4115 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4116}
4117
4118
ager@chromium.org7c537e22008-10-16 08:43:32 +00004119void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004120 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004121 set_elements(storage);
4122}
4123
4124
lrn@chromium.org303ada72010-10-27 09:33:13 +00004125MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004126 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004127 return GetHeap()->CopyFixedArray(this);
4128}
4129
4130
4131Relocatable::Relocatable(Isolate* isolate) {
4132 ASSERT(isolate == Isolate::Current());
4133 isolate_ = isolate;
4134 prev_ = isolate->relocatable_top();
4135 isolate->set_relocatable_top(this);
4136}
4137
4138
4139Relocatable::~Relocatable() {
4140 ASSERT(isolate_ == Isolate::Current());
4141 ASSERT_EQ(isolate_->relocatable_top(), this);
4142 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004143}
4144
4145
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004146int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4147 return map->instance_size();
4148}
4149
4150
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004151void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004152 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004153 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004154}
4155
4156
4157template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004158void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004159 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004160 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004161}
4162
4163
4164void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4165 typedef v8::String::ExternalAsciiStringResource Resource;
4166 v->VisitExternalAsciiString(
4167 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4168}
4169
4170
4171template<typename StaticVisitor>
4172void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4173 typedef v8::String::ExternalAsciiStringResource Resource;
4174 StaticVisitor::VisitExternalAsciiString(
4175 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4176}
4177
4178
4179void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4180 typedef v8::String::ExternalStringResource Resource;
4181 v->VisitExternalTwoByteString(
4182 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4183}
4184
4185
4186template<typename StaticVisitor>
4187void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4188 typedef v8::String::ExternalStringResource Resource;
4189 StaticVisitor::VisitExternalTwoByteString(
4190 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4191}
4192
4193#define SLOT_ADDR(obj, offset) \
4194 reinterpret_cast<Object**>((obj)->address() + offset)
4195
4196template<int start_offset, int end_offset, int size>
4197void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4198 HeapObject* obj,
4199 ObjectVisitor* v) {
4200 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4201}
4202
4203
4204template<int start_offset>
4205void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4206 int object_size,
4207 ObjectVisitor* v) {
4208 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4209}
4210
4211#undef SLOT_ADDR
4212
4213
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004214#undef CAST_ACCESSOR
4215#undef INT_ACCESSORS
4216#undef SMI_ACCESSORS
4217#undef ACCESSORS
4218#undef FIELD_ADDR
4219#undef READ_FIELD
4220#undef WRITE_FIELD
4221#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004222#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004223#undef READ_MEMADDR_FIELD
4224#undef WRITE_MEMADDR_FIELD
4225#undef READ_DOUBLE_FIELD
4226#undef WRITE_DOUBLE_FIELD
4227#undef READ_INT_FIELD
4228#undef WRITE_INT_FIELD
4229#undef READ_SHORT_FIELD
4230#undef WRITE_SHORT_FIELD
4231#undef READ_BYTE_FIELD
4232#undef WRITE_BYTE_FIELD
4233
4234
4235} } // namespace v8::internal
4236
4237#endif // V8_OBJECTS_INL_H_