blob: f955d334d20b7403826a3c877d091ea01d9ab955 [file] [log] [blame]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001// Copyright 2010 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"
42#include "memory.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"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
49PropertyDetails::PropertyDetails(Smi* smi) {
50 value_ = smi->value();
51}
52
53
54Smi* PropertyDetails::AsSmi() {
55 return Smi::FromInt(value_);
56}
57
58
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000059PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000060 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000061 return PropertyDetails(smi);
62}
63
64
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000065#define CAST_ACCESSOR(type) \
66 type* type::cast(Object* object) { \
67 ASSERT(object->Is##type()); \
68 return reinterpret_cast<type*>(object); \
69 }
70
71
72#define INT_ACCESSORS(holder, name, offset) \
73 int holder::name() { return READ_INT_FIELD(this, offset); } \
74 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
75
76
77#define ACCESSORS(holder, name, type, offset) \
78 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000081 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000082 }
83
84
85#define SMI_ACCESSORS(holder, name, offset) \
86 int holder::name() { \
87 Object* value = READ_FIELD(this, offset); \
88 return Smi::cast(value)->value(); \
89 } \
90 void holder::set_##name(int value) { \
91 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
92 }
93
94
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000095#define BOOL_GETTER(holder, field, name, offset) \
96 bool holder::name() { \
97 return BooleanBit::get(field(), offset); \
98 } \
99
100
101#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000102 bool holder::name() { \
103 return BooleanBit::get(field(), offset); \
104 } \
105 void holder::set_##name(bool value) { \
106 set_##field(BooleanBit::set(field(), offset, value)); \
107 }
108
109
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000110bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
111 // There is a constraint on the object; check.
112 if (!this->IsJSObject()) return false;
113 // Fetch the constructor function of the object.
114 Object* cons_obj = JSObject::cast(this)->map()->constructor();
115 if (!cons_obj->IsJSFunction()) return false;
116 JSFunction* fun = JSFunction::cast(cons_obj);
117 // Iterate through the chain of inheriting function templates to
118 // see if the required one occurs.
119 for (Object* type = fun->shared()->function_data();
120 type->IsFunctionTemplateInfo();
121 type = FunctionTemplateInfo::cast(type)->parent_template()) {
122 if (type == expected) return true;
123 }
124 // Didn't find the required type in the inheritance chain.
125 return false;
126}
127
128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000129bool Object::IsSmi() {
130 return HAS_SMI_TAG(this);
131}
132
133
134bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000135 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000136}
137
138
139bool Object::IsHeapNumber() {
140 return Object::IsHeapObject()
141 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
142}
143
144
145bool Object::IsString() {
146 return Object::IsHeapObject()
147 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
148}
149
150
ager@chromium.org870a0b62008-11-04 11:43:05 +0000151bool Object::IsSymbol() {
152 if (!this->IsHeapObject()) return false;
153 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000154 // Because the symbol tag is non-zero and no non-string types have the
155 // symbol bit set we can test for symbols with a very simple test
156 // operation.
157 ASSERT(kSymbolTag != 0);
158 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
159 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000160}
161
162
163bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000164 if (!this->IsHeapObject()) return false;
165 uint32_t type = HeapObject::cast(this)->map()->instance_type();
166 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
167 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000168}
169
170
ager@chromium.org870a0b62008-11-04 11:43:05 +0000171bool Object::IsSeqString() {
172 if (!IsString()) return false;
173 return StringShape(String::cast(this)).IsSequential();
174}
175
176
177bool Object::IsSeqAsciiString() {
178 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000179 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000180 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181}
182
183
184bool Object::IsSeqTwoByteString() {
185 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000186 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000187 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000188}
189
190
191bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000192 if (!IsString()) return false;
193 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194}
195
196
197bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000198 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000199 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000200 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201}
202
203
204bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000205 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000206 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000207 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208}
209
210
ager@chromium.org870a0b62008-11-04 11:43:05 +0000211StringShape::StringShape(String* str)
212 : type_(str->map()->instance_type()) {
213 set_valid();
214 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215}
216
217
ager@chromium.org870a0b62008-11-04 11:43:05 +0000218StringShape::StringShape(Map* map)
219 : type_(map->instance_type()) {
220 set_valid();
221 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222}
223
224
ager@chromium.org870a0b62008-11-04 11:43:05 +0000225StringShape::StringShape(InstanceType t)
226 : type_(static_cast<uint32_t>(t)) {
227 set_valid();
228 ASSERT((type_ & kIsNotStringMask) == kStringTag);
229}
230
231
232bool StringShape::IsSymbol() {
233 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000234 ASSERT(kSymbolTag != 0);
235 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000236}
237
238
ager@chromium.org5ec48922009-05-05 07:25:34 +0000239bool String::IsAsciiRepresentation() {
240 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000241 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242}
243
244
ager@chromium.org5ec48922009-05-05 07:25:34 +0000245bool String::IsTwoByteRepresentation() {
246 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000247 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000248}
249
250
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000251bool String::HasOnlyAsciiChars() {
252 uint32_t type = map()->instance_type();
253 return (type & kStringEncodingMask) == kAsciiStringTag ||
254 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000255}
256
257
ager@chromium.org870a0b62008-11-04 11:43:05 +0000258bool StringShape::IsCons() {
259 return (type_ & kStringRepresentationMask) == kConsStringTag;
260}
261
262
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263bool StringShape::IsExternal() {
264 return (type_ & kStringRepresentationMask) == kExternalStringTag;
265}
266
267
268bool StringShape::IsSequential() {
269 return (type_ & kStringRepresentationMask) == kSeqStringTag;
270}
271
272
273StringRepresentationTag StringShape::representation_tag() {
274 uint32_t tag = (type_ & kStringRepresentationMask);
275 return static_cast<StringRepresentationTag>(tag);
276}
277
278
279uint32_t StringShape::full_representation_tag() {
280 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
281}
282
283
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000284STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
285 Internals::kFullStringRepresentationMask);
286
287
ager@chromium.org870a0b62008-11-04 11:43:05 +0000288bool StringShape::IsSequentialAscii() {
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
290}
291
292
293bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
298bool StringShape::IsExternalAscii() {
299 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305}
306
307
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000308STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
309 Internals::kExternalTwoByteRepresentationTag);
310
311
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312uc32 FlatStringReader::Get(int index) {
313 ASSERT(0 <= index && index <= length_);
314 if (is_ascii_) {
315 return static_cast<const byte*>(start_)[index];
316 } else {
317 return static_cast<const uc16*>(start_)[index];
318 }
319}
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322bool Object::IsNumber() {
323 return IsSmi() || IsHeapNumber();
324}
325
326
327bool Object::IsByteArray() {
328 return Object::IsHeapObject()
329 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
330}
331
332
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000333bool Object::IsPixelArray() {
334 return Object::IsHeapObject() &&
335 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
336}
337
338
ager@chromium.org3811b432009-10-28 14:53:37 +0000339bool Object::IsExternalArray() {
340 if (!Object::IsHeapObject())
341 return false;
342 InstanceType instance_type =
343 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000344 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
345 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000346}
347
348
349bool Object::IsExternalByteArray() {
350 return Object::IsHeapObject() &&
351 HeapObject::cast(this)->map()->instance_type() ==
352 EXTERNAL_BYTE_ARRAY_TYPE;
353}
354
355
356bool Object::IsExternalUnsignedByteArray() {
357 return Object::IsHeapObject() &&
358 HeapObject::cast(this)->map()->instance_type() ==
359 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
360}
361
362
363bool Object::IsExternalShortArray() {
364 return Object::IsHeapObject() &&
365 HeapObject::cast(this)->map()->instance_type() ==
366 EXTERNAL_SHORT_ARRAY_TYPE;
367}
368
369
370bool Object::IsExternalUnsignedShortArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalIntArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_INT_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalUnsignedIntArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalFloatArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_FLOAT_ARRAY_TYPE;
395}
396
397
lrn@chromium.org303ada72010-10-27 09:33:13 +0000398bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000399 return HAS_FAILURE_TAG(this);
400}
401
402
lrn@chromium.org303ada72010-10-27 09:33:13 +0000403bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
lrn@chromium.org303ada72010-10-27 09:33:13 +0000409bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000410 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000411 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000412}
413
414
lrn@chromium.org303ada72010-10-27 09:33:13 +0000415bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000416 return this == Failure::Exception();
417}
418
419
lrn@chromium.org303ada72010-10-27 09:33:13 +0000420bool MaybeObject::IsTheHole() {
421 return this == Heap::the_hole_value();
422}
423
424
425Failure* Failure::cast(MaybeObject* obj) {
426 ASSERT(HAS_FAILURE_TAG(obj));
427 return reinterpret_cast<Failure*>(obj);
428}
429
430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431bool Object::IsJSObject() {
432 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000433 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434}
435
436
ager@chromium.org32912102009-01-16 10:38:43 +0000437bool Object::IsJSContextExtensionObject() {
438 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000439 && (HeapObject::cast(this)->map()->instance_type() ==
440 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000441}
442
443
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444bool Object::IsMap() {
445 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000446 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000447}
448
449
450bool Object::IsFixedArray() {
451 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000452 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000453}
454
455
456bool Object::IsDescriptorArray() {
457 return IsFixedArray();
458}
459
460
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000461bool Object::IsDeoptimizationInputData() {
462 // Must be a fixed array.
463 if (!IsFixedArray()) return false;
464
465 // There's no sure way to detect the difference between a fixed array and
466 // a deoptimization data array. Since this is used for asserts we can
467 // check that the length is zero or else the fixed size plus a multiple of
468 // the entry size.
469 int length = FixedArray::cast(this)->length();
470 if (length == 0) return true;
471
472 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
473 return length >= 0 &&
474 length % DeoptimizationInputData::kDeoptEntrySize == 0;
475}
476
477
478bool Object::IsDeoptimizationOutputData() {
479 if (!IsFixedArray()) return false;
480 // There's actually no way to see the difference between a fixed array and
481 // a deoptimization data array. Since this is used for asserts we can check
482 // that the length is plausible though.
483 if (FixedArray::cast(this)->length() % 2 != 0) return false;
484 return true;
485}
486
487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000488bool Object::IsContext() {
489 return Object::IsHeapObject()
490 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000491 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492 HeapObject::cast(this)->map() == Heap::global_context_map());
493}
494
495
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000496bool Object::IsCatchContext() {
497 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000498 && HeapObject::cast(this)->map() == Heap::catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000499}
500
501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502bool Object::IsGlobalContext() {
503 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000504 && HeapObject::cast(this)->map() == Heap::global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000505}
506
507
508bool Object::IsJSFunction() {
509 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000510 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000511}
512
513
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000514template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000515 return obj->IsJSFunction();
516}
517
518
519bool Object::IsCode() {
520 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000521 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522}
523
524
525bool Object::IsOddball() {
526 return Object::IsHeapObject()
527 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
528}
529
530
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000531bool Object::IsJSGlobalPropertyCell() {
532 return Object::IsHeapObject()
533 && HeapObject::cast(this)->map()->instance_type()
534 == JS_GLOBAL_PROPERTY_CELL_TYPE;
535}
536
537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538bool Object::IsSharedFunctionInfo() {
539 return Object::IsHeapObject() &&
540 (HeapObject::cast(this)->map()->instance_type() ==
541 SHARED_FUNCTION_INFO_TYPE);
542}
543
544
545bool Object::IsJSValue() {
546 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000547 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
548}
549
550
551bool Object::IsJSMessageObject() {
552 return Object::IsHeapObject()
553 && (HeapObject::cast(this)->map()->instance_type() ==
554 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000555}
556
557
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000558bool Object::IsStringWrapper() {
559 return IsJSValue() && JSValue::cast(this)->value()->IsString();
560}
561
562
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000563bool Object::IsProxy() {
564 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000565 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566}
567
568
569bool Object::IsBoolean() {
570 return IsTrue() || IsFalse();
571}
572
573
574bool Object::IsJSArray() {
575 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000576 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577}
578
579
ager@chromium.org236ad962008-09-25 09:45:57 +0000580bool Object::IsJSRegExp() {
581 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000582 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000583}
584
585
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000586template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587 return obj->IsJSArray();
588}
589
590
591bool Object::IsHashTable() {
592 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000593 && HeapObject::cast(this)->map() == Heap::hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594}
595
596
597bool Object::IsDictionary() {
598 return IsHashTable() && this != Heap::symbol_table();
599}
600
601
602bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000603 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000604}
605
606
ager@chromium.orgac091b72010-05-05 07:34:42 +0000607bool Object::IsJSFunctionResultCache() {
608 if (!IsFixedArray()) return false;
609 FixedArray* self = FixedArray::cast(this);
610 int length = self->length();
611 if (length < JSFunctionResultCache::kEntriesIndex) return false;
612 if ((length - JSFunctionResultCache::kEntriesIndex)
613 % JSFunctionResultCache::kEntrySize != 0) {
614 return false;
615 }
616#ifdef DEBUG
617 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
618#endif
619 return true;
620}
621
622
ricow@chromium.org65fae842010-08-25 15:26:24 +0000623bool Object::IsNormalizedMapCache() {
624 if (!IsFixedArray()) return false;
625 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
626 return false;
627 }
628#ifdef DEBUG
629 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
630#endif
631 return true;
632}
633
634
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000635bool Object::IsCompilationCacheTable() {
636 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000637}
638
639
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000640bool Object::IsCodeCacheHashTable() {
641 return IsHashTable();
642}
643
644
ager@chromium.org236ad962008-09-25 09:45:57 +0000645bool Object::IsMapCache() {
646 return IsHashTable();
647}
648
649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650bool Object::IsPrimitive() {
651 return IsOddball() || IsNumber() || IsString();
652}
653
654
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000655bool Object::IsJSGlobalProxy() {
656 bool result = IsHeapObject() &&
657 (HeapObject::cast(this)->map()->instance_type() ==
658 JS_GLOBAL_PROXY_TYPE);
659 ASSERT(!result || IsAccessCheckNeeded());
660 return result;
661}
662
663
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000664bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000665 if (!IsHeapObject()) return false;
666
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000667 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000668 return type == JS_GLOBAL_OBJECT_TYPE ||
669 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670}
671
672
673bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000674 return IsHeapObject() &&
675 (HeapObject::cast(this)->map()->instance_type() ==
676 JS_GLOBAL_OBJECT_TYPE);
677}
678
679
680bool Object::IsJSBuiltinsObject() {
681 return IsHeapObject() &&
682 (HeapObject::cast(this)->map()->instance_type() ==
683 JS_BUILTINS_OBJECT_TYPE);
684}
685
686
687bool Object::IsUndetectableObject() {
688 return IsHeapObject()
689 && HeapObject::cast(this)->map()->is_undetectable();
690}
691
692
693bool Object::IsAccessCheckNeeded() {
694 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000695 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696}
697
698
699bool Object::IsStruct() {
700 if (!IsHeapObject()) return false;
701 switch (HeapObject::cast(this)->map()->instance_type()) {
702#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
703 STRUCT_LIST(MAKE_STRUCT_CASE)
704#undef MAKE_STRUCT_CASE
705 default: return false;
706 }
707}
708
709
710#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
711 bool Object::Is##Name() { \
712 return Object::IsHeapObject() \
713 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
714 }
715 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
716#undef MAKE_STRUCT_PREDICATE
717
718
719bool Object::IsUndefined() {
720 return this == Heap::undefined_value();
721}
722
723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724bool Object::IsNull() {
725 return this == Heap::null_value();
726}
727
728
729bool Object::IsTrue() {
730 return this == Heap::true_value();
731}
732
733
734bool Object::IsFalse() {
735 return this == Heap::false_value();
736}
737
738
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000739bool Object::IsArgumentsMarker() {
740 return this == Heap::arguments_marker();
741}
742
743
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000744double Object::Number() {
745 ASSERT(IsNumber());
746 return IsSmi()
747 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
748 : reinterpret_cast<HeapNumber*>(this)->value();
749}
750
751
752
lrn@chromium.org303ada72010-10-27 09:33:13 +0000753MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754 if (IsSmi()) return this;
755 if (IsHeapNumber()) {
756 double value = HeapNumber::cast(this)->value();
757 int int_value = FastD2I(value);
758 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
759 return Smi::FromInt(int_value);
760 }
761 }
762 return Failure::Exception();
763}
764
765
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000766bool Object::HasSpecificClassOf(String* name) {
767 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
768}
769
770
lrn@chromium.org303ada72010-10-27 09:33:13 +0000771MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000772 // GetElement can trigger a getter which can cause allocation.
773 // This was not always the case. This ASSERT is here to catch
774 // leftover incorrect uses.
775 ASSERT(Heap::IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000776 return GetElementWithReceiver(this, index);
777}
778
779
lrn@chromium.org303ada72010-10-27 09:33:13 +0000780Object* Object::GetElementNoExceptionThrown(uint32_t index) {
781 MaybeObject* maybe = GetElementWithReceiver(this, index);
782 ASSERT(!maybe->IsFailure());
783 Object* result = NULL; // Initialization to please compiler.
784 maybe->ToObject(&result);
785 return result;
786}
787
788
789MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790 PropertyAttributes attributes;
791 return GetPropertyWithReceiver(this, key, &attributes);
792}
793
794
lrn@chromium.org303ada72010-10-27 09:33:13 +0000795MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796 return GetPropertyWithReceiver(this, key, attributes);
797}
798
799
800#define FIELD_ADDR(p, offset) \
801 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
802
803#define READ_FIELD(p, offset) \
804 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
805
806#define WRITE_FIELD(p, offset, value) \
807 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
808
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000809
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810#define WRITE_BARRIER(object, offset) \
811 Heap::RecordWrite(object->address(), offset);
812
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000813// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000814// write due to the assert validating the written value.
815#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
816 if (mode == UPDATE_WRITE_BARRIER) { \
817 Heap::RecordWrite(object->address(), offset); \
818 } else { \
819 ASSERT(mode == SKIP_WRITE_BARRIER); \
820 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000821 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000822 Page::FromAddress(object->address())-> \
823 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000824 }
825
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826#define READ_DOUBLE_FIELD(p, offset) \
827 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
828
829#define WRITE_DOUBLE_FIELD(p, offset, value) \
830 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
831
832#define READ_INT_FIELD(p, offset) \
833 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
834
835#define WRITE_INT_FIELD(p, offset, value) \
836 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
837
ager@chromium.org3e875802009-06-29 08:26:34 +0000838#define READ_INTPTR_FIELD(p, offset) \
839 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
840
841#define WRITE_INTPTR_FIELD(p, offset, value) \
842 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
843
ager@chromium.org7c537e22008-10-16 08:43:32 +0000844#define READ_UINT32_FIELD(p, offset) \
845 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
846
847#define WRITE_UINT32_FIELD(p, offset, value) \
848 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
849
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850#define READ_SHORT_FIELD(p, offset) \
851 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
852
853#define WRITE_SHORT_FIELD(p, offset, value) \
854 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
855
856#define READ_BYTE_FIELD(p, offset) \
857 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
858
859#define WRITE_BYTE_FIELD(p, offset, value) \
860 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
861
862
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000863Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
864 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865}
866
867
868int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000869 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870}
871
872
873Smi* Smi::FromInt(int value) {
874 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000875 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000876 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000877 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000878 return reinterpret_cast<Smi*>(tagged_value);
879}
880
881
882Smi* Smi::FromIntptr(intptr_t value) {
883 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000884 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
885 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000886}
887
888
889Failure::Type Failure::type() const {
890 return static_cast<Type>(value() & kFailureTypeTagMask);
891}
892
893
894bool Failure::IsInternalError() const {
895 return type() == INTERNAL_ERROR;
896}
897
898
899bool Failure::IsOutOfMemoryException() const {
900 return type() == OUT_OF_MEMORY_EXCEPTION;
901}
902
903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904AllocationSpace Failure::allocation_space() const {
905 ASSERT_EQ(RETRY_AFTER_GC, type());
906 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
907 & kSpaceTagMask);
908}
909
910
911Failure* Failure::InternalError() {
912 return Construct(INTERNAL_ERROR);
913}
914
915
916Failure* Failure::Exception() {
917 return Construct(EXCEPTION);
918}
919
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000920
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000921Failure* Failure::OutOfMemoryException() {
922 return Construct(OUT_OF_MEMORY_EXCEPTION);
923}
924
925
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000926intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000927 return static_cast<intptr_t>(
928 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000929}
930
931
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000932Failure* Failure::RetryAfterGC() {
933 return RetryAfterGC(NEW_SPACE);
934}
935
936
937Failure* Failure::RetryAfterGC(AllocationSpace space) {
938 ASSERT((space & ~kSpaceTagMask) == 0);
939 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000940}
941
942
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000943Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000944 uintptr_t info =
945 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000946 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000948}
949
950
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000951bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952#ifdef DEBUG
953 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
954#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000955
956#ifdef V8_TARGET_ARCH_X64
957 // To be representable as a long smi, the value must be a 32-bit integer.
958 bool result = (value == static_cast<int32_t>(value));
959#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000960 // To be representable as an tagged small integer, the two
961 // most-significant bits of 'value' must be either 00 or 11 due to
962 // sign-extension. To check this we add 01 to the two
963 // most-significant bits, and check if the most-significant bit is 0
964 //
965 // CAUTION: The original code below:
966 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
967 // may lead to incorrect results according to the C language spec, and
968 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
969 // compiler may produce undefined results in case of signed integer
970 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000971 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000972#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000973 ASSERT(result == in_range);
974 return result;
975}
976
977
kasper.lund7276f142008-07-30 08:49:36 +0000978MapWord MapWord::FromMap(Map* map) {
979 return MapWord(reinterpret_cast<uintptr_t>(map));
980}
981
982
983Map* MapWord::ToMap() {
984 return reinterpret_cast<Map*>(value_);
985}
986
987
988bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000989 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000990}
991
992
993MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000994 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
995 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000996}
997
998
999HeapObject* MapWord::ToForwardingAddress() {
1000 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001001 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001002}
1003
1004
1005bool MapWord::IsMarked() {
1006 return (value_ & kMarkingMask) == 0;
1007}
1008
1009
1010void MapWord::SetMark() {
1011 value_ &= ~kMarkingMask;
1012}
1013
1014
1015void MapWord::ClearMark() {
1016 value_ |= kMarkingMask;
1017}
1018
1019
1020bool MapWord::IsOverflowed() {
1021 return (value_ & kOverflowMask) != 0;
1022}
1023
1024
1025void MapWord::SetOverflow() {
1026 value_ |= kOverflowMask;
1027}
1028
1029
1030void MapWord::ClearOverflow() {
1031 value_ &= ~kOverflowMask;
1032}
1033
1034
1035MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1036 // Offset is the distance in live bytes from the first live object in the
1037 // same page. The offset between two objects in the same page should not
1038 // exceed the object area size of a page.
1039 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1040
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001041 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001042 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1043
1044 Page* map_page = Page::FromAddress(map_address);
1045 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1046
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001047 uintptr_t map_page_offset =
1048 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001049
1050 uintptr_t encoding =
1051 (compact_offset << kForwardingOffsetShift) |
1052 (map_page_offset << kMapPageOffsetShift) |
1053 (map_page->mc_page_index << kMapPageIndexShift);
1054 return MapWord(encoding);
1055}
1056
1057
1058Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001059 int map_page_index =
1060 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001061 ASSERT_MAP_PAGE_INDEX(map_page_index);
1062
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001063 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001064 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1065 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001066
1067 return (map_space->PageAddress(map_page_index) + map_page_offset);
1068}
1069
1070
1071int MapWord::DecodeOffset() {
1072 // The offset field is represented in the kForwardingOffsetBits
1073 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001074 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1075 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1076 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001077}
1078
1079
1080MapWord MapWord::FromEncodedAddress(Address address) {
1081 return MapWord(reinterpret_cast<uintptr_t>(address));
1082}
1083
1084
1085Address MapWord::ToEncodedAddress() {
1086 return reinterpret_cast<Address>(value_);
1087}
1088
1089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090#ifdef DEBUG
1091void HeapObject::VerifyObjectField(int offset) {
1092 VerifyPointer(READ_FIELD(this, offset));
1093}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001094
1095void HeapObject::VerifySmiField(int offset) {
1096 ASSERT(READ_FIELD(this, offset)->IsSmi());
1097}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098#endif
1099
1100
1101Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001102 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001103}
1104
1105
1106void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001107 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108}
1109
1110
kasper.lund7276f142008-07-30 08:49:36 +00001111MapWord HeapObject::map_word() {
1112 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1113}
1114
1115
1116void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001117 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001118 // here.
1119 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1120}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001121
1122
1123HeapObject* HeapObject::FromAddress(Address address) {
1124 ASSERT_TAG_ALIGNED(address);
1125 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1126}
1127
1128
1129Address HeapObject::address() {
1130 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1131}
1132
1133
1134int HeapObject::Size() {
1135 return SizeFromMap(map());
1136}
1137
1138
1139void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1140 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1141 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1142}
1143
1144
1145void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1146 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1147}
1148
1149
kasper.lund7276f142008-07-30 08:49:36 +00001150bool HeapObject::IsMarked() {
1151 return map_word().IsMarked();
1152}
1153
1154
1155void HeapObject::SetMark() {
1156 ASSERT(!IsMarked());
1157 MapWord first_word = map_word();
1158 first_word.SetMark();
1159 set_map_word(first_word);
1160}
1161
1162
1163void HeapObject::ClearMark() {
1164 ASSERT(IsMarked());
1165 MapWord first_word = map_word();
1166 first_word.ClearMark();
1167 set_map_word(first_word);
1168}
1169
1170
1171bool HeapObject::IsOverflowed() {
1172 return map_word().IsOverflowed();
1173}
1174
1175
1176void HeapObject::SetOverflow() {
1177 MapWord first_word = map_word();
1178 first_word.SetOverflow();
1179 set_map_word(first_word);
1180}
1181
1182
1183void HeapObject::ClearOverflow() {
1184 ASSERT(IsOverflowed());
1185 MapWord first_word = map_word();
1186 first_word.ClearOverflow();
1187 set_map_word(first_word);
1188}
1189
1190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001191double HeapNumber::value() {
1192 return READ_DOUBLE_FIELD(this, kValueOffset);
1193}
1194
1195
1196void HeapNumber::set_value(double value) {
1197 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1198}
1199
1200
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001201int HeapNumber::get_exponent() {
1202 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1203 kExponentShift) - kExponentBias;
1204}
1205
1206
1207int HeapNumber::get_sign() {
1208 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1209}
1210
1211
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001212ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001213
1214
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001215HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001216 Object* array = READ_FIELD(this, kElementsOffset);
1217 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001218 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1219 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001220 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001221}
1222
1223
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001224void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001225 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001226 (value->map() == Heap::fixed_array_map() ||
1227 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001228 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001229 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1230 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001231 WRITE_FIELD(this, kElementsOffset, value);
1232 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1233}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234
1235
1236void JSObject::initialize_properties() {
1237 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1238 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1239}
1240
1241
1242void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001243 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1245 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1246}
1247
1248
lrn@chromium.org303ada72010-10-27 09:33:13 +00001249MaybeObject* JSObject::ResetElements() {
1250 Object* obj;
1251 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1252 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1253 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001254 set_map(Map::cast(obj));
1255 initialize_elements();
1256 return this;
1257}
1258
1259
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001260ACCESSORS(Oddball, to_string, String, kToStringOffset)
1261ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1262
1263
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001264Object* JSGlobalPropertyCell::value() {
1265 return READ_FIELD(this, kValueOffset);
1266}
1267
1268
1269void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1270 // The write barrier is not used for global property cells.
1271 ASSERT(!val->IsJSGlobalPropertyCell());
1272 WRITE_FIELD(this, kValueOffset, val);
1273}
1274
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001276int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001277 InstanceType type = map()->instance_type();
1278 // Check for the most common kind of JavaScript object before
1279 // falling into the generic switch. This speeds up the internal
1280 // field operations considerably on average.
1281 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1282 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001283 case JS_GLOBAL_PROXY_TYPE:
1284 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001285 case JS_GLOBAL_OBJECT_TYPE:
1286 return JSGlobalObject::kSize;
1287 case JS_BUILTINS_OBJECT_TYPE:
1288 return JSBuiltinsObject::kSize;
1289 case JS_FUNCTION_TYPE:
1290 return JSFunction::kSize;
1291 case JS_VALUE_TYPE:
1292 return JSValue::kSize;
1293 case JS_ARRAY_TYPE:
1294 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001295 case JS_REGEXP_TYPE:
1296 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001297 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001298 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001299 case JS_MESSAGE_OBJECT_TYPE:
1300 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301 default:
1302 UNREACHABLE();
1303 return 0;
1304 }
1305}
1306
1307
1308int JSObject::GetInternalFieldCount() {
1309 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001310 // Make sure to adjust for the number of in-object properties. These
1311 // properties do contribute to the size, but are not internal fields.
1312 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1313 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001314}
1315
1316
1317Object* JSObject::GetInternalField(int index) {
1318 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001319 // Internal objects do follow immediately after the header, whereas in-object
1320 // properties are at the end of the object. Therefore there is no need
1321 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1323}
1324
1325
1326void JSObject::SetInternalField(int index, Object* value) {
1327 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001328 // Internal objects do follow immediately after the header, whereas in-object
1329 // properties are at the end of the object. Therefore there is no need
1330 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331 int offset = GetHeaderSize() + (kPointerSize * index);
1332 WRITE_FIELD(this, offset, value);
1333 WRITE_BARRIER(this, offset);
1334}
1335
1336
ager@chromium.org7c537e22008-10-16 08:43:32 +00001337// Access fast-case object properties at index. The use of these routines
1338// is needed to correctly distinguish between properties stored in-object and
1339// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001340Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001341 // Adjust for the number of properties stored in the object.
1342 index -= map()->inobject_properties();
1343 if (index < 0) {
1344 int offset = map()->instance_size() + (index * kPointerSize);
1345 return READ_FIELD(this, offset);
1346 } else {
1347 ASSERT(index < properties()->length());
1348 return properties()->get(index);
1349 }
1350}
1351
1352
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001353Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001354 // Adjust for the number of properties stored in the object.
1355 index -= map()->inobject_properties();
1356 if (index < 0) {
1357 int offset = map()->instance_size() + (index * kPointerSize);
1358 WRITE_FIELD(this, offset, value);
1359 WRITE_BARRIER(this, offset);
1360 } else {
1361 ASSERT(index < properties()->length());
1362 properties()->set(index, value);
1363 }
1364 return value;
1365}
1366
1367
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001368Object* JSObject::InObjectPropertyAt(int index) {
1369 // Adjust for the number of properties stored in the object.
1370 index -= map()->inobject_properties();
1371 ASSERT(index < 0);
1372 int offset = map()->instance_size() + (index * kPointerSize);
1373 return READ_FIELD(this, offset);
1374}
1375
1376
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001377Object* JSObject::InObjectPropertyAtPut(int index,
1378 Object* value,
1379 WriteBarrierMode mode) {
1380 // Adjust for the number of properties stored in the object.
1381 index -= map()->inobject_properties();
1382 ASSERT(index < 0);
1383 int offset = map()->instance_size() + (index * kPointerSize);
1384 WRITE_FIELD(this, offset, value);
1385 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1386 return value;
1387}
1388
1389
1390
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001391void JSObject::InitializeBody(int object_size, Object* value) {
1392 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001393 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001394 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395 }
1396}
1397
1398
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001399bool JSObject::HasFastProperties() {
1400 return !properties()->IsDictionary();
1401}
1402
1403
1404int JSObject::MaxFastProperties() {
1405 // Allow extra fast properties if the object has more than
1406 // kMaxFastProperties in-object properties. When this is the case,
1407 // it is very unlikely that the object is being used as a dictionary
1408 // and there is a good chance that allowing more map transitions
1409 // will be worth it.
1410 return Max(map()->inobject_properties(), kMaxFastProperties);
1411}
1412
1413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001415 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001416 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001417 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418 }
1419}
1420
1421
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001422bool Object::ToArrayIndex(uint32_t* index) {
1423 if (IsSmi()) {
1424 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425 if (value < 0) return false;
1426 *index = value;
1427 return true;
1428 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001429 if (IsHeapNumber()) {
1430 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431 uint32_t uint_value = static_cast<uint32_t>(value);
1432 if (value == static_cast<double>(uint_value)) {
1433 *index = uint_value;
1434 return true;
1435 }
1436 }
1437 return false;
1438}
1439
1440
1441bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1442 if (!this->IsJSValue()) return false;
1443
1444 JSValue* js_value = JSValue::cast(this);
1445 if (!js_value->value()->IsString()) return false;
1446
1447 String* str = String::cast(js_value->value());
1448 if (index >= (uint32_t)str->length()) return false;
1449
1450 return true;
1451}
1452
1453
1454Object* FixedArray::get(int index) {
1455 ASSERT(index >= 0 && index < this->length());
1456 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1457}
1458
1459
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001460void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001461 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001462 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1463 int offset = kHeaderSize + index * kPointerSize;
1464 WRITE_FIELD(this, offset, value);
1465}
1466
1467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001469 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001470 ASSERT(index >= 0 && index < this->length());
1471 int offset = kHeaderSize + index * kPointerSize;
1472 WRITE_FIELD(this, offset, value);
1473 WRITE_BARRIER(this, offset);
1474}
1475
1476
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001477WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001478 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1479 return UPDATE_WRITE_BARRIER;
1480}
1481
1482
1483void FixedArray::set(int index,
1484 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001485 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001486 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001487 ASSERT(index >= 0 && index < this->length());
1488 int offset = kHeaderSize + index * kPointerSize;
1489 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001490 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491}
1492
1493
1494void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001495 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001497 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1499}
1500
1501
1502void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001503 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001504 ASSERT(index >= 0 && index < this->length());
1505 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1506 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1507 Heap::undefined_value());
1508}
1509
1510
ager@chromium.org236ad962008-09-25 09:45:57 +00001511void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001512 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001513 ASSERT(index >= 0 && index < this->length());
1514 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1515 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1516}
1517
1518
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001519void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001520 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 ASSERT(index >= 0 && index < this->length());
1522 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1523 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1524}
1525
1526
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001527void FixedArray::set_unchecked(int index, Smi* value) {
1528 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1529 int offset = kHeaderSize + index * kPointerSize;
1530 WRITE_FIELD(this, offset, value);
1531}
1532
1533
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001534void FixedArray::set_unchecked(int index,
1535 Object* value,
1536 WriteBarrierMode mode) {
1537 int offset = kHeaderSize + index * kPointerSize;
1538 WRITE_FIELD(this, offset, value);
1539 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1540}
1541
1542
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001543void FixedArray::set_null_unchecked(int index) {
1544 ASSERT(index >= 0 && index < this->length());
1545 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1546 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1547}
1548
1549
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001550Object** FixedArray::data_start() {
1551 return HeapObject::RawField(this, kHeaderSize);
1552}
1553
1554
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001555bool DescriptorArray::IsEmpty() {
1556 ASSERT(this == Heap::empty_descriptor_array() ||
1557 this->length() > 2);
1558 return this == Heap::empty_descriptor_array();
1559}
1560
1561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001562void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1563 Object* tmp = array->get(first);
1564 fast_set(array, first, array->get(second));
1565 fast_set(array, second, tmp);
1566}
1567
1568
1569int DescriptorArray::Search(String* name) {
1570 SLOW_ASSERT(IsSortedNoDuplicates());
1571
1572 // Check for empty descriptor array.
1573 int nof = number_of_descriptors();
1574 if (nof == 0) return kNotFound;
1575
1576 // Fast case: do linear search for small arrays.
1577 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001578 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001579 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580 }
1581
1582 // Slow case: perform binary search.
1583 return BinarySearch(name, 0, nof - 1);
1584}
1585
1586
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001587int DescriptorArray::SearchWithCache(String* name) {
1588 int number = DescriptorLookupCache::Lookup(this, name);
1589 if (number == DescriptorLookupCache::kAbsent) {
1590 number = Search(name);
1591 DescriptorLookupCache::Update(this, name, number);
1592 }
1593 return number;
1594}
1595
1596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001597String* DescriptorArray::GetKey(int descriptor_number) {
1598 ASSERT(descriptor_number < number_of_descriptors());
1599 return String::cast(get(ToKeyIndex(descriptor_number)));
1600}
1601
1602
1603Object* DescriptorArray::GetValue(int descriptor_number) {
1604 ASSERT(descriptor_number < number_of_descriptors());
1605 return GetContentArray()->get(ToValueIndex(descriptor_number));
1606}
1607
1608
1609Smi* DescriptorArray::GetDetails(int descriptor_number) {
1610 ASSERT(descriptor_number < number_of_descriptors());
1611 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1612}
1613
1614
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001615PropertyType DescriptorArray::GetType(int descriptor_number) {
1616 ASSERT(descriptor_number < number_of_descriptors());
1617 return PropertyDetails(GetDetails(descriptor_number)).type();
1618}
1619
1620
1621int DescriptorArray::GetFieldIndex(int descriptor_number) {
1622 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1623}
1624
1625
1626JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1627 return JSFunction::cast(GetValue(descriptor_number));
1628}
1629
1630
1631Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1632 ASSERT(GetType(descriptor_number) == CALLBACKS);
1633 return GetValue(descriptor_number);
1634}
1635
1636
1637AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1638 ASSERT(GetType(descriptor_number) == CALLBACKS);
1639 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1640 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1641}
1642
1643
1644bool DescriptorArray::IsProperty(int descriptor_number) {
1645 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1646}
1647
1648
1649bool DescriptorArray::IsTransition(int descriptor_number) {
1650 PropertyType t = GetType(descriptor_number);
1651 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1652}
1653
1654
1655bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1656 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1657}
1658
1659
1660bool DescriptorArray::IsDontEnum(int descriptor_number) {
1661 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1662}
1663
1664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001665void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1666 desc->Init(GetKey(descriptor_number),
1667 GetValue(descriptor_number),
1668 GetDetails(descriptor_number));
1669}
1670
1671
1672void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1673 // Range check.
1674 ASSERT(descriptor_number < number_of_descriptors());
1675
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001676 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1678 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1679
1680 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1681 FixedArray* content_array = GetContentArray();
1682 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1683 fast_set(content_array, ToDetailsIndex(descriptor_number),
1684 desc->GetDetails().AsSmi());
1685}
1686
1687
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001688void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1689 Descriptor desc;
1690 src->Get(src_index, &desc);
1691 Set(index, &desc);
1692}
1693
1694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695void DescriptorArray::Swap(int first, int second) {
1696 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1697 FixedArray* content_array = GetContentArray();
1698 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1699 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1700}
1701
1702
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001703bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001704 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705 if (!max_index_object->IsSmi()) return false;
1706 return 0 !=
1707 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1708}
1709
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001710uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001711 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001712 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001713 if (!max_index_object->IsSmi()) return 0;
1714 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1715 return value >> kRequiresSlowElementsTagSize;
1716}
1717
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001718void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001719 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001720}
1721
1722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001723// ------------------------------------
1724// Cast operations
1725
1726
1727CAST_ACCESSOR(FixedArray)
1728CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001729CAST_ACCESSOR(DeoptimizationInputData)
1730CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001732CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001733CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001734CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001735CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001736CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737CAST_ACCESSOR(String)
1738CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001739CAST_ACCESSOR(SeqAsciiString)
1740CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742CAST_ACCESSOR(ExternalString)
1743CAST_ACCESSOR(ExternalAsciiString)
1744CAST_ACCESSOR(ExternalTwoByteString)
1745CAST_ACCESSOR(JSObject)
1746CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747CAST_ACCESSOR(HeapObject)
1748CAST_ACCESSOR(HeapNumber)
1749CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001750CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001751CAST_ACCESSOR(SharedFunctionInfo)
1752CAST_ACCESSOR(Map)
1753CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001754CAST_ACCESSOR(GlobalObject)
1755CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756CAST_ACCESSOR(JSGlobalObject)
1757CAST_ACCESSOR(JSBuiltinsObject)
1758CAST_ACCESSOR(Code)
1759CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001760CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761CAST_ACCESSOR(Proxy)
1762CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001763CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001764CAST_ACCESSOR(ExternalArray)
1765CAST_ACCESSOR(ExternalByteArray)
1766CAST_ACCESSOR(ExternalUnsignedByteArray)
1767CAST_ACCESSOR(ExternalShortArray)
1768CAST_ACCESSOR(ExternalUnsignedShortArray)
1769CAST_ACCESSOR(ExternalIntArray)
1770CAST_ACCESSOR(ExternalUnsignedIntArray)
1771CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772CAST_ACCESSOR(Struct)
1773
1774
1775#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1776 STRUCT_LIST(MAKE_STRUCT_CAST)
1777#undef MAKE_STRUCT_CAST
1778
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001779
1780template <typename Shape, typename Key>
1781HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 ASSERT(obj->IsHashTable());
1783 return reinterpret_cast<HashTable*>(obj);
1784}
1785
1786
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001787SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1788SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1789
1790INT_ACCESSORS(PixelArray, length, kLengthOffset)
1791INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792
1793
ager@chromium.orgac091b72010-05-05 07:34:42 +00001794SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001795
1796
1797uint32_t String::hash_field() {
1798 return READ_UINT32_FIELD(this, kHashFieldOffset);
1799}
1800
1801
1802void String::set_hash_field(uint32_t value) {
1803 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001804#if V8_HOST_ARCH_64_BIT
1805 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1806#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001807}
1808
1809
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810bool String::Equals(String* other) {
1811 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001812 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1813 return false;
1814 }
1815 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816}
1817
1818
lrn@chromium.org303ada72010-10-27 09:33:13 +00001819MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001820 if (!StringShape(this).IsCons()) return this;
1821 ConsString* cons = ConsString::cast(this);
1822 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001823 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824}
1825
1826
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001827String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001828 MaybeObject* flat = TryFlatten(pretenure);
1829 Object* successfully_flattened;
1830 if (flat->ToObject(&successfully_flattened)) {
1831 return String::cast(successfully_flattened);
1832 }
1833 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001834}
1835
1836
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001837uint16_t String::Get(int index) {
1838 ASSERT(index >= 0 && index < length());
1839 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001840 case kSeqStringTag | kAsciiStringTag:
1841 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1842 case kSeqStringTag | kTwoByteStringTag:
1843 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1844 case kConsStringTag | kAsciiStringTag:
1845 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001847 case kExternalStringTag | kAsciiStringTag:
1848 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1849 case kExternalStringTag | kTwoByteStringTag:
1850 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 default:
1852 break;
1853 }
1854
1855 UNREACHABLE();
1856 return 0;
1857}
1858
1859
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001860void String::Set(int index, uint16_t value) {
1861 ASSERT(index >= 0 && index < length());
1862 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863
ager@chromium.org5ec48922009-05-05 07:25:34 +00001864 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001865 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1866 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001867}
1868
1869
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001870bool String::IsFlat() {
1871 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001872 case kConsStringTag: {
1873 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001874 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001875 return second->length() == 0;
1876 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001877 default:
1878 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001879 }
1880}
1881
1882
ager@chromium.org7c537e22008-10-16 08:43:32 +00001883uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884 ASSERT(index >= 0 && index < length());
1885 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1886}
1887
1888
ager@chromium.org7c537e22008-10-16 08:43:32 +00001889void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1891 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1892 static_cast<byte>(value));
1893}
1894
1895
ager@chromium.org7c537e22008-10-16 08:43:32 +00001896Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001897 return FIELD_ADDR(this, kHeaderSize);
1898}
1899
1900
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001901char* SeqAsciiString::GetChars() {
1902 return reinterpret_cast<char*>(GetCharsAddress());
1903}
1904
1905
ager@chromium.org7c537e22008-10-16 08:43:32 +00001906Address SeqTwoByteString::GetCharsAddress() {
1907 return FIELD_ADDR(this, kHeaderSize);
1908}
1909
1910
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001911uc16* SeqTwoByteString::GetChars() {
1912 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1913}
1914
1915
ager@chromium.org7c537e22008-10-16 08:43:32 +00001916uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001917 ASSERT(index >= 0 && index < length());
1918 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1919}
1920
1921
ager@chromium.org7c537e22008-10-16 08:43:32 +00001922void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001923 ASSERT(index >= 0 && index < length());
1924 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1925}
1926
1927
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001928int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001929 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930}
1931
1932
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001933int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001934 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001935}
1936
1937
ager@chromium.org870a0b62008-11-04 11:43:05 +00001938String* ConsString::first() {
1939 return String::cast(READ_FIELD(this, kFirstOffset));
1940}
1941
1942
1943Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001944 return READ_FIELD(this, kFirstOffset);
1945}
1946
1947
ager@chromium.org870a0b62008-11-04 11:43:05 +00001948void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001950 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001951}
1952
1953
ager@chromium.org870a0b62008-11-04 11:43:05 +00001954String* ConsString::second() {
1955 return String::cast(READ_FIELD(this, kSecondOffset));
1956}
1957
1958
1959Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001960 return READ_FIELD(this, kSecondOffset);
1961}
1962
1963
ager@chromium.org870a0b62008-11-04 11:43:05 +00001964void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001966 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001967}
1968
1969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001970ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1971 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1972}
1973
1974
1975void ExternalAsciiString::set_resource(
1976 ExternalAsciiString::Resource* resource) {
1977 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1978}
1979
1980
1981ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1982 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1983}
1984
1985
1986void ExternalTwoByteString::set_resource(
1987 ExternalTwoByteString::Resource* resource) {
1988 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1989}
1990
1991
ager@chromium.orgac091b72010-05-05 07:34:42 +00001992void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001993 set_finger_index(kEntriesIndex);
1994 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001995}
1996
1997
1998void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001999 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002000 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002001 MemsetPointer(entries_start,
2002 Heap::the_hole_value(),
2003 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002004 MakeZeroSize();
2005}
2006
2007
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002008int JSFunctionResultCache::size() {
2009 return Smi::cast(get(kCacheSizeIndex))->value();
2010}
2011
2012
2013void JSFunctionResultCache::set_size(int size) {
2014 set(kCacheSizeIndex, Smi::FromInt(size));
2015}
2016
2017
2018int JSFunctionResultCache::finger_index() {
2019 return Smi::cast(get(kFingerIndex))->value();
2020}
2021
2022
2023void JSFunctionResultCache::set_finger_index(int finger_index) {
2024 set(kFingerIndex, Smi::FromInt(finger_index));
2025}
2026
2027
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028byte ByteArray::get(int index) {
2029 ASSERT(index >= 0 && index < this->length());
2030 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2031}
2032
2033
2034void ByteArray::set(int index, byte value) {
2035 ASSERT(index >= 0 && index < this->length());
2036 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2037}
2038
2039
2040int ByteArray::get_int(int index) {
2041 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2042 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2043}
2044
2045
2046ByteArray* ByteArray::FromDataStartAddress(Address address) {
2047 ASSERT_TAG_ALIGNED(address);
2048 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2049}
2050
2051
2052Address ByteArray::GetDataStartAddress() {
2053 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2054}
2055
2056
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002057uint8_t* PixelArray::external_pointer() {
2058 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2059 return reinterpret_cast<uint8_t*>(ptr);
2060}
2061
2062
2063void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
2064 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2065 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2066}
2067
2068
2069uint8_t PixelArray::get(int index) {
2070 ASSERT((index >= 0) && (index < this->length()));
2071 uint8_t* ptr = external_pointer();
2072 return ptr[index];
2073}
2074
2075
2076void PixelArray::set(int index, uint8_t value) {
2077 ASSERT((index >= 0) && (index < this->length()));
2078 uint8_t* ptr = external_pointer();
2079 ptr[index] = value;
2080}
2081
2082
ager@chromium.org3811b432009-10-28 14:53:37 +00002083void* ExternalArray::external_pointer() {
2084 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2085 return reinterpret_cast<void*>(ptr);
2086}
2087
2088
2089void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2090 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2091 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2092}
2093
2094
2095int8_t ExternalByteArray::get(int index) {
2096 ASSERT((index >= 0) && (index < this->length()));
2097 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2098 return ptr[index];
2099}
2100
2101
2102void ExternalByteArray::set(int index, int8_t value) {
2103 ASSERT((index >= 0) && (index < this->length()));
2104 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2105 ptr[index] = value;
2106}
2107
2108
2109uint8_t ExternalUnsignedByteArray::get(int index) {
2110 ASSERT((index >= 0) && (index < this->length()));
2111 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2112 return ptr[index];
2113}
2114
2115
2116void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2117 ASSERT((index >= 0) && (index < this->length()));
2118 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2119 ptr[index] = value;
2120}
2121
2122
2123int16_t ExternalShortArray::get(int index) {
2124 ASSERT((index >= 0) && (index < this->length()));
2125 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2126 return ptr[index];
2127}
2128
2129
2130void ExternalShortArray::set(int index, int16_t value) {
2131 ASSERT((index >= 0) && (index < this->length()));
2132 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2133 ptr[index] = value;
2134}
2135
2136
2137uint16_t ExternalUnsignedShortArray::get(int index) {
2138 ASSERT((index >= 0) && (index < this->length()));
2139 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2140 return ptr[index];
2141}
2142
2143
2144void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2145 ASSERT((index >= 0) && (index < this->length()));
2146 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2147 ptr[index] = value;
2148}
2149
2150
2151int32_t ExternalIntArray::get(int index) {
2152 ASSERT((index >= 0) && (index < this->length()));
2153 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2154 return ptr[index];
2155}
2156
2157
2158void ExternalIntArray::set(int index, int32_t value) {
2159 ASSERT((index >= 0) && (index < this->length()));
2160 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2161 ptr[index] = value;
2162}
2163
2164
2165uint32_t ExternalUnsignedIntArray::get(int index) {
2166 ASSERT((index >= 0) && (index < this->length()));
2167 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2168 return ptr[index];
2169}
2170
2171
2172void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2173 ASSERT((index >= 0) && (index < this->length()));
2174 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2175 ptr[index] = value;
2176}
2177
2178
2179float ExternalFloatArray::get(int index) {
2180 ASSERT((index >= 0) && (index < this->length()));
2181 float* ptr = static_cast<float*>(external_pointer());
2182 return ptr[index];
2183}
2184
2185
2186void ExternalFloatArray::set(int index, float value) {
2187 ASSERT((index >= 0) && (index < this->length()));
2188 float* ptr = static_cast<float*>(external_pointer());
2189 ptr[index] = value;
2190}
2191
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002192
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002193int Map::visitor_id() {
2194 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2195}
2196
2197
2198void Map::set_visitor_id(int id) {
2199 ASSERT(0 <= id && id < 256);
2200 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2201}
2202
ager@chromium.org3811b432009-10-28 14:53:37 +00002203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002205 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2206}
2207
2208
2209int Map::inobject_properties() {
2210 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211}
2212
2213
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002214int Map::pre_allocated_property_fields() {
2215 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2216}
2217
2218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002219int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002220 int instance_size = map->instance_size();
2221 if (instance_size != kVariableSizeSentinel) return instance_size;
2222 // We can ignore the "symbol" bit becase it is only set for symbols
2223 // and implies a string type.
2224 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002225 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002227 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002229 if (instance_type == ASCII_STRING_TYPE) {
2230 return SeqAsciiString::SizeFor(
2231 reinterpret_cast<SeqAsciiString*>(this)->length());
2232 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002233 if (instance_type == BYTE_ARRAY_TYPE) {
2234 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2235 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002236 if (instance_type == STRING_TYPE) {
2237 return SeqTwoByteString::SizeFor(
2238 reinterpret_cast<SeqTwoByteString*>(this)->length());
2239 }
2240 ASSERT(instance_type == CODE_TYPE);
2241 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242}
2243
2244
2245void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002246 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002247 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248 ASSERT(0 <= value && value < 256);
2249 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2250}
2251
2252
ager@chromium.org7c537e22008-10-16 08:43:32 +00002253void Map::set_inobject_properties(int value) {
2254 ASSERT(0 <= value && value < 256);
2255 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2256}
2257
2258
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002259void Map::set_pre_allocated_property_fields(int value) {
2260 ASSERT(0 <= value && value < 256);
2261 WRITE_BYTE_FIELD(this,
2262 kPreAllocatedPropertyFieldsOffset,
2263 static_cast<byte>(value));
2264}
2265
2266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267InstanceType Map::instance_type() {
2268 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2269}
2270
2271
2272void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2274}
2275
2276
2277int Map::unused_property_fields() {
2278 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2279}
2280
2281
2282void Map::set_unused_property_fields(int value) {
2283 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2284}
2285
2286
2287byte Map::bit_field() {
2288 return READ_BYTE_FIELD(this, kBitFieldOffset);
2289}
2290
2291
2292void Map::set_bit_field(byte value) {
2293 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2294}
2295
2296
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002297byte Map::bit_field2() {
2298 return READ_BYTE_FIELD(this, kBitField2Offset);
2299}
2300
2301
2302void Map::set_bit_field2(byte value) {
2303 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2304}
2305
2306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307void Map::set_non_instance_prototype(bool value) {
2308 if (value) {
2309 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2310 } else {
2311 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2312 }
2313}
2314
2315
2316bool Map::has_non_instance_prototype() {
2317 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2318}
2319
2320
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002321void Map::set_function_with_prototype(bool value) {
2322 if (value) {
2323 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2324 } else {
2325 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2326 }
2327}
2328
2329
2330bool Map::function_with_prototype() {
2331 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2332}
2333
2334
ager@chromium.org870a0b62008-11-04 11:43:05 +00002335void Map::set_is_access_check_needed(bool access_check_needed) {
2336 if (access_check_needed) {
2337 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2338 } else {
2339 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2340 }
2341}
2342
2343
2344bool Map::is_access_check_needed() {
2345 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2346}
2347
2348
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002349void Map::set_is_extensible(bool value) {
2350 if (value) {
2351 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2352 } else {
2353 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2354 }
2355}
2356
2357bool Map::is_extensible() {
2358 return ((1 << kIsExtensible) & bit_field2()) != 0;
2359}
2360
2361
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002362void Map::set_attached_to_shared_function_info(bool value) {
2363 if (value) {
2364 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2365 } else {
2366 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2367 }
2368}
2369
2370bool Map::attached_to_shared_function_info() {
2371 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2372}
2373
2374
2375void Map::set_is_shared(bool value) {
2376 if (value) {
2377 set_bit_field2(bit_field2() | (1 << kIsShared));
2378 } else {
2379 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2380 }
2381}
2382
2383bool Map::is_shared() {
2384 return ((1 << kIsShared) & bit_field2()) != 0;
2385}
2386
2387
2388JSFunction* Map::unchecked_constructor() {
2389 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2390}
2391
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393Code::Flags Code::flags() {
2394 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2395}
2396
2397
2398void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002399 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002401 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2402 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 ExtractArgumentsCountFromFlags(flags) >= 0);
2404 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2405}
2406
2407
2408Code::Kind Code::kind() {
2409 return ExtractKindFromFlags(flags());
2410}
2411
2412
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002413InLoopFlag Code::ic_in_loop() {
2414 return ExtractICInLoopFromFlags(flags());
2415}
2416
2417
kasper.lund7276f142008-07-30 08:49:36 +00002418InlineCacheState Code::ic_state() {
2419 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420 // Only allow uninitialized or debugger states for non-IC code
2421 // objects. This is used in the debugger to determine whether or not
2422 // a call to code object has been replaced with a debug break call.
2423 ASSERT(is_inline_cache_stub() ||
2424 result == UNINITIALIZED ||
2425 result == DEBUG_BREAK ||
2426 result == DEBUG_PREPARE_STEP_IN);
2427 return result;
2428}
2429
2430
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002431Code::ExtraICState Code::extra_ic_state() {
2432 ASSERT(is_inline_cache_stub());
2433 return ExtractExtraICStateFromFlags(flags());
2434}
2435
2436
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002438 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439 return ExtractTypeFromFlags(flags());
2440}
2441
2442
2443int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002444 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445 return ExtractArgumentsCountFromFlags(flags());
2446}
2447
2448
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002449int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002450 ASSERT(kind() == STUB ||
2451 kind() == BINARY_OP_IC ||
2452 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2453 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002454 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002455}
2456
2457
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002458void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459 ASSERT(kind() == STUB ||
2460 kind() == BINARY_OP_IC ||
2461 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2462 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002463 ASSERT(0 <= major && major < 256);
2464 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465}
2466
2467
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002468bool Code::optimizable() {
2469 ASSERT(kind() == FUNCTION);
2470 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2471}
2472
2473
2474void Code::set_optimizable(bool value) {
2475 ASSERT(kind() == FUNCTION);
2476 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2477}
2478
2479
2480bool Code::has_deoptimization_support() {
2481 ASSERT(kind() == FUNCTION);
2482 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2483}
2484
2485
2486void Code::set_has_deoptimization_support(bool value) {
2487 ASSERT(kind() == FUNCTION);
2488 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2489}
2490
2491
2492int Code::allow_osr_at_loop_nesting_level() {
2493 ASSERT(kind() == FUNCTION);
2494 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2495}
2496
2497
2498void Code::set_allow_osr_at_loop_nesting_level(int level) {
2499 ASSERT(kind() == FUNCTION);
2500 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2501 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2502}
2503
2504
2505unsigned Code::stack_slots() {
2506 ASSERT(kind() == OPTIMIZED_FUNCTION);
2507 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2508}
2509
2510
2511void Code::set_stack_slots(unsigned slots) {
2512 ASSERT(kind() == OPTIMIZED_FUNCTION);
2513 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2514}
2515
2516
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002517unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002519 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520}
2521
2522
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002523void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002524 ASSERT(kind() == OPTIMIZED_FUNCTION);
2525 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002526 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002527}
2528
2529
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002530unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002532 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533}
2534
2535
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002536void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002537 ASSERT(kind() == FUNCTION);
2538 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002539 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540}
2541
2542
2543CheckType Code::check_type() {
2544 ASSERT(is_call_stub() || is_keyed_call_stub());
2545 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2546 return static_cast<CheckType>(type);
2547}
2548
2549
2550void Code::set_check_type(CheckType value) {
2551 ASSERT(is_call_stub() || is_keyed_call_stub());
2552 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2553}
2554
2555
2556byte Code::binary_op_type() {
2557 ASSERT(is_binary_op_stub());
2558 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2559}
2560
2561
2562void Code::set_binary_op_type(byte value) {
2563 ASSERT(is_binary_op_stub());
2564 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2565}
2566
2567
2568byte Code::type_recording_binary_op_type() {
2569 ASSERT(is_type_recording_binary_op_stub());
2570 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2571}
2572
2573
2574void Code::set_type_recording_binary_op_type(byte value) {
2575 ASSERT(is_type_recording_binary_op_stub());
2576 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2577}
2578
2579
2580byte Code::type_recording_binary_op_result_type() {
2581 ASSERT(is_type_recording_binary_op_stub());
2582 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2583}
2584
2585
2586void Code::set_type_recording_binary_op_result_type(byte value) {
2587 ASSERT(is_type_recording_binary_op_stub());
2588 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2589}
2590
2591
2592byte Code::compare_state() {
2593 ASSERT(is_compare_ic_stub());
2594 return READ_BYTE_FIELD(this, kCompareStateOffset);
2595}
2596
2597
2598void Code::set_compare_state(byte value) {
2599 ASSERT(is_compare_ic_stub());
2600 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2601}
2602
2603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002604bool Code::is_inline_cache_stub() {
2605 Kind kind = this->kind();
2606 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2607}
2608
2609
2610Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002611 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002612 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002613 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002614 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002615 int argc,
2616 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002617 // Extra IC state is only allowed for monomorphic call IC stubs
2618 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002619 ASSERT(extra_ic_state == kNoExtraICState ||
2620 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002621 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
2622 (kind == STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623 // Compute the bit mask.
2624 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002625 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002626 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002627 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002628 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002629 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002630 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002631 // Cast to flags and validate result before returning it.
2632 Flags result = static_cast<Flags>(bits);
2633 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002634 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002635 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002637 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002638 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2639 return result;
2640}
2641
2642
2643Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2644 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002645 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002646 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002647 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002649 return ComputeFlags(
2650 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002651}
2652
2653
2654Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2655 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2656 return static_cast<Kind>(bits);
2657}
2658
2659
kasper.lund7276f142008-07-30 08:49:36 +00002660InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2661 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002662 return static_cast<InlineCacheState>(bits);
2663}
2664
2665
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002666Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2667 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2668 return static_cast<ExtraICState>(bits);
2669}
2670
2671
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002672InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2673 int bits = (flags & kFlagsICInLoopMask);
2674 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2675}
2676
2677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002678PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2679 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2680 return static_cast<PropertyType>(bits);
2681}
2682
2683
2684int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2685 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2686}
2687
2688
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002689InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2690 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2691 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2692}
2693
2694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002695Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2696 int bits = flags & ~kFlagsTypeMask;
2697 return static_cast<Flags>(bits);
2698}
2699
2700
ager@chromium.org8bb60582008-12-11 12:02:20 +00002701Code* Code::GetCodeFromTargetAddress(Address address) {
2702 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2703 // GetCodeFromTargetAddress might be called when marking objects during mark
2704 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2705 // Code::cast. Code::cast does not work when the object's map is
2706 // marked.
2707 Code* result = reinterpret_cast<Code*>(code);
2708 return result;
2709}
2710
2711
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002712Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2713 return HeapObject::
2714 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2715}
2716
2717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718Object* Map::prototype() {
2719 return READ_FIELD(this, kPrototypeOffset);
2720}
2721
2722
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002723void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002724 ASSERT(value->IsNull() || value->IsJSObject());
2725 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002726 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002727}
2728
2729
lrn@chromium.org303ada72010-10-27 09:33:13 +00002730MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002731 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002732 Object* obj;
2733 { MaybeObject* maybe_obj = CopyDropTransitions();
2734 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2735 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002736 Map* new_map = Map::cast(obj);
2737 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002738 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002739 return new_map;
2740}
2741
2742
lrn@chromium.org303ada72010-10-27 09:33:13 +00002743MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002744 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002745 Object* obj;
2746 { MaybeObject* maybe_obj = CopyDropTransitions();
2747 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2748 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002749 Map* new_map = Map::cast(obj);
2750 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002751 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002752 return new_map;
2753}
2754
2755
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002756MaybeObject* Map::GetPixelArrayElementsMap() {
2757 if (has_pixel_array_elements()) return this;
2758 // TODO(danno): Special case empty object map (or most common case)
2759 // to return a pre-canned pixel array map.
2760 Object* obj;
2761 { MaybeObject* maybe_obj = CopyDropTransitions();
2762 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2763 }
2764 Map* new_map = Map::cast(obj);
2765 new_map->set_has_fast_elements(false);
2766 new_map->set_has_pixel_array_elements(true);
2767 Counters::map_to_pixel_array_elements.Increment();
2768 return new_map;
2769}
2770
2771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002772ACCESSORS(Map, instance_descriptors, DescriptorArray,
2773 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002774ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002775ACCESSORS(Map, constructor, Object, kConstructorOffset)
2776
2777ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2778ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002780
2781ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2782ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002783ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002785ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786
2787ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2788ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2789ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2790ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2791ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2792
2793ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2794ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2795ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2796
2797ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2798ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2799ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2800ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2801ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2802ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2803
2804ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2805ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2806
2807ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2808ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2809
2810ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2811ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2813 kPropertyAccessorsOffset)
2814ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2815 kPrototypeTemplateOffset)
2816ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2817ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2818 kNamedPropertyHandlerOffset)
2819ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2820 kIndexedPropertyHandlerOffset)
2821ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2822 kInstanceTemplateOffset)
2823ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2824ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2826 kInstanceCallHandlerOffset)
2827ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2828 kAccessCheckInfoOffset)
2829ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2830
2831ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002832ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2833 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834
2835ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2836ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2837
2838ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2839
2840ACCESSORS(Script, source, Object, kSourceOffset)
2841ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002842ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2844ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002845ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002846ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002847ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2848ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002849ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002850ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002851ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002852ACCESSORS(Script, eval_from_instructions_offset, Smi,
2853 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002855#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002856ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2857ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2858ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2859ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2860
2861ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2862ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2863ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2864ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002865#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002866
2867ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002868ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002869ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002870ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2871 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002872ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002873ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2874ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002875ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002876ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2877 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002878
2879BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2880 kHiddenPrototypeBit)
2881BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2882BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2883 kNeedsAccessCheckBit)
2884BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2885 kIsExpressionBit)
2886BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2887 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002888BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002889 has_only_simple_this_property_assignments,
2890 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002891BOOL_ACCESSORS(SharedFunctionInfo,
2892 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002893 try_full_codegen,
2894 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002895BOOL_ACCESSORS(SharedFunctionInfo,
2896 compiler_hints,
2897 allows_lazy_compilation,
2898 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002899
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002900
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002901#if V8_HOST_ARCH_32_BIT
2902SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2903SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002905SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002906 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002907SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2908SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002910SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2911SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002913SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002914 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002915SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002916 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002918#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002919
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002920#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002921 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002922 int holder::name() { \
2923 int value = READ_INT_FIELD(this, offset); \
2924 ASSERT(kHeapObjectTag == 1); \
2925 ASSERT((value & kHeapObjectTag) == 0); \
2926 return value >> 1; \
2927 } \
2928 void holder::set_##name(int value) { \
2929 ASSERT(kHeapObjectTag == 1); \
2930 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2931 (value & 0xC0000000) == 0x000000000); \
2932 WRITE_INT_FIELD(this, \
2933 offset, \
2934 (value << 1) & ~kHeapObjectTag); \
2935 }
2936
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002937#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2938 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002939 INT_ACCESSORS(holder, name, offset)
2940
2941
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002942PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002943PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2944 formal_parameter_count,
2945 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002946
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002947PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2948 expected_nof_properties,
2949 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002950PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2951
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002952PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
2953PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2954 start_position_and_type,
2955 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002956
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002957PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2958 function_token_position,
2959 kFunctionTokenPositionOffset)
2960PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2961 compiler_hints,
2962 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002963
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002964PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2965 this_property_assignments_count,
2966 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002967PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002968#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002969
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002970
2971int SharedFunctionInfo::construction_count() {
2972 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2973}
2974
2975
2976void SharedFunctionInfo::set_construction_count(int value) {
2977 ASSERT(0 <= value && value < 256);
2978 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2979}
2980
2981
2982bool SharedFunctionInfo::live_objects_may_exist() {
2983 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2984}
2985
2986
2987void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2988 if (value) {
2989 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2990 } else {
2991 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2992 }
2993}
2994
2995
2996bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2997 return initial_map() != Heap::undefined_value();
2998}
2999
3000
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001bool SharedFunctionInfo::optimization_disabled() {
3002 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3003}
3004
3005
3006void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3007 set_compiler_hints(BooleanBit::set(compiler_hints(),
3008 kOptimizationDisabled,
3009 disable));
3010 // If disabling optimizations we reflect that in the code object so
3011 // it will not be counted as optimizable code.
3012 if ((code()->kind() == Code::FUNCTION) && disable) {
3013 code()->set_optimizable(false);
3014 }
3015}
3016
3017
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003018bool SharedFunctionInfo::strict_mode() {
3019 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3020}
3021
3022
3023void SharedFunctionInfo::set_strict_mode(bool value) {
3024 set_compiler_hints(BooleanBit::set(compiler_hints(),
3025 kStrictModeFunction,
3026 value));
3027}
3028
3029
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003030ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3031ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3032
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003033bool Script::HasValidSource() {
3034 Object* src = this->source();
3035 if (!src->IsString()) return true;
3036 String* src_str = String::cast(src);
3037 if (!StringShape(src_str).IsExternal()) return true;
3038 if (src_str->IsAsciiRepresentation()) {
3039 return ExternalAsciiString::cast(src)->resource() != NULL;
3040 } else if (src_str->IsTwoByteRepresentation()) {
3041 return ExternalTwoByteString::cast(src)->resource() != NULL;
3042 }
3043 return true;
3044}
3045
3046
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003047void SharedFunctionInfo::DontAdaptArguments() {
3048 ASSERT(code()->kind() == Code::BUILTIN);
3049 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3050}
3051
3052
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053int SharedFunctionInfo::start_position() {
3054 return start_position_and_type() >> kStartPositionShift;
3055}
3056
3057
3058void SharedFunctionInfo::set_start_position(int start_position) {
3059 set_start_position_and_type((start_position << kStartPositionShift)
3060 | (start_position_and_type() & ~kStartPositionMask));
3061}
3062
3063
3064Code* SharedFunctionInfo::code() {
3065 return Code::cast(READ_FIELD(this, kCodeOffset));
3066}
3067
3068
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003069Code* SharedFunctionInfo::unchecked_code() {
3070 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3071}
3072
3073
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003074void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003075 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003076 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003077}
3078
3079
ager@chromium.orgb5737492010-07-15 09:29:43 +00003080SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3081 return reinterpret_cast<SerializedScopeInfo*>(
3082 READ_FIELD(this, kScopeInfoOffset));
3083}
3084
3085
3086void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3087 WriteBarrierMode mode) {
3088 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3089 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3090}
3091
3092
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093Smi* SharedFunctionInfo::deopt_counter() {
3094 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3095}
3096
3097
3098void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3099 WRITE_FIELD(this, kDeoptCounterOffset, value);
3100}
3101
3102
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003103bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003104 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003105}
3106
3107
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003108bool SharedFunctionInfo::IsApiFunction() {
3109 return function_data()->IsFunctionTemplateInfo();
3110}
3111
3112
3113FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3114 ASSERT(IsApiFunction());
3115 return FunctionTemplateInfo::cast(function_data());
3116}
3117
3118
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003119bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003120 return function_data()->IsSmi();
3121}
3122
3123
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003124BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3125 ASSERT(HasBuiltinFunctionId());
3126 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003127}
3128
3129
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003130int SharedFunctionInfo::code_age() {
3131 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3132}
3133
3134
3135void SharedFunctionInfo::set_code_age(int code_age) {
3136 set_compiler_hints(compiler_hints() |
3137 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3138}
3139
3140
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141bool SharedFunctionInfo::has_deoptimization_support() {
3142 Code* code = this->code();
3143 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3144}
3145
3146
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003147bool JSFunction::IsBuiltin() {
3148 return context()->global()->IsJSBuiltinsObject();
3149}
3150
3151
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003152bool JSFunction::NeedsArgumentsAdaption() {
3153 return shared()->formal_parameter_count() !=
3154 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3155}
3156
3157
3158bool JSFunction::IsOptimized() {
3159 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3160}
3161
3162
3163bool JSFunction::IsMarkedForLazyRecompilation() {
3164 return code() == Builtins::builtin(Builtins::LazyRecompile);
3165}
3166
3167
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003169 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170}
3171
3172
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003173Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003174 return reinterpret_cast<Code*>(
3175 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003176}
3177
3178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003179void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003180 // Skip the write barrier because code is never in new space.
3181 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003182 Address entry = value->entry();
3183 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003184}
3185
3186
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003187void JSFunction::ReplaceCode(Code* code) {
3188 bool was_optimized = IsOptimized();
3189 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3190
3191 set_code(code);
3192
3193 // Add/remove the function from the list of optimized functions for this
3194 // context based on the state change.
3195 if (!was_optimized && is_optimized) {
3196 context()->global_context()->AddOptimizedFunction(this);
3197 }
3198 if (was_optimized && !is_optimized) {
3199 context()->global_context()->RemoveOptimizedFunction(this);
3200 }
3201}
3202
3203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003204Context* JSFunction::context() {
3205 return Context::cast(READ_FIELD(this, kContextOffset));
3206}
3207
3208
3209Object* JSFunction::unchecked_context() {
3210 return READ_FIELD(this, kContextOffset);
3211}
3212
3213
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003214SharedFunctionInfo* JSFunction::unchecked_shared() {
3215 return reinterpret_cast<SharedFunctionInfo*>(
3216 READ_FIELD(this, kSharedFunctionInfoOffset));
3217}
3218
3219
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003220void JSFunction::set_context(Object* value) {
3221 ASSERT(value == Heap::undefined_value() || value->IsContext());
3222 WRITE_FIELD(this, kContextOffset, value);
3223 WRITE_BARRIER(this, kContextOffset);
3224}
3225
3226ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3227 kPrototypeOrInitialMapOffset)
3228
3229
3230Map* JSFunction::initial_map() {
3231 return Map::cast(prototype_or_initial_map());
3232}
3233
3234
3235void JSFunction::set_initial_map(Map* value) {
3236 set_prototype_or_initial_map(value);
3237}
3238
3239
3240bool JSFunction::has_initial_map() {
3241 return prototype_or_initial_map()->IsMap();
3242}
3243
3244
3245bool JSFunction::has_instance_prototype() {
3246 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3247}
3248
3249
3250bool JSFunction::has_prototype() {
3251 return map()->has_non_instance_prototype() || has_instance_prototype();
3252}
3253
3254
3255Object* JSFunction::instance_prototype() {
3256 ASSERT(has_instance_prototype());
3257 if (has_initial_map()) return initial_map()->prototype();
3258 // When there is no initial map and the prototype is a JSObject, the
3259 // initial map field is used for the prototype field.
3260 return prototype_or_initial_map();
3261}
3262
3263
3264Object* JSFunction::prototype() {
3265 ASSERT(has_prototype());
3266 // If the function's prototype property has been set to a non-JSObject
3267 // value, that value is stored in the constructor field of the map.
3268 if (map()->has_non_instance_prototype()) return map()->constructor();
3269 return instance_prototype();
3270}
3271
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003272bool JSFunction::should_have_prototype() {
3273 return map()->function_with_prototype();
3274}
3275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003276
3277bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003278 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003279}
3280
3281
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003282int JSFunction::NumberOfLiterals() {
3283 return literals()->length();
3284}
3285
3286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003288 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003289 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003290}
3291
3292
3293void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3294 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003295 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003296 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3297 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3298}
3299
3300
3301Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003302 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003303 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3304}
3305
3306
3307void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3308 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003309 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003310 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3311 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312}
3313
3314
3315Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003316 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003317}
3318
3319
3320void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003321 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322}
3323
3324
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325ACCESSORS(JSValue, value, Object, kValueOffset)
3326
3327
3328JSValue* JSValue::cast(Object* obj) {
3329 ASSERT(obj->IsJSValue());
3330 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3331 return reinterpret_cast<JSValue*>(obj);
3332}
3333
3334
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003335ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3336ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3337ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3338ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3339ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3340SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3341SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3342
3343
3344JSMessageObject* JSMessageObject::cast(Object* obj) {
3345 ASSERT(obj->IsJSMessageObject());
3346 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3347 return reinterpret_cast<JSMessageObject*>(obj);
3348}
3349
3350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003352ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003353ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003354
3355
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003356byte* Code::instruction_start() {
3357 return FIELD_ADDR(this, kHeaderSize);
3358}
3359
3360
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003361byte* Code::instruction_end() {
3362 return instruction_start() + instruction_size();
3363}
3364
3365
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003367 return RoundUp(instruction_size(), kObjectAlignment);
3368}
3369
3370
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003371FixedArray* Code::unchecked_deoptimization_data() {
3372 return reinterpret_cast<FixedArray*>(
3373 READ_FIELD(this, kDeoptimizationDataOffset));
3374}
3375
3376
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003377ByteArray* Code::unchecked_relocation_info() {
3378 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379}
3380
3381
3382byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003383 return unchecked_relocation_info()->GetDataStartAddress();
3384}
3385
3386
3387int Code::relocation_size() {
3388 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003389}
3390
3391
3392byte* Code::entry() {
3393 return instruction_start();
3394}
3395
3396
3397bool Code::contains(byte* pc) {
3398 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003399 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400}
3401
3402
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003403ACCESSORS(JSArray, length, Object, kLengthOffset)
3404
3405
ager@chromium.org236ad962008-09-25 09:45:57 +00003406ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003407
3408
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003409JSRegExp::Type JSRegExp::TypeTag() {
3410 Object* data = this->data();
3411 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3412 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3413 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003414}
3415
3416
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003417int JSRegExp::CaptureCount() {
3418 switch (TypeTag()) {
3419 case ATOM:
3420 return 0;
3421 case IRREGEXP:
3422 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3423 default:
3424 UNREACHABLE();
3425 return -1;
3426 }
3427}
3428
3429
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003430JSRegExp::Flags JSRegExp::GetFlags() {
3431 ASSERT(this->data()->IsFixedArray());
3432 Object* data = this->data();
3433 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3434 return Flags(smi->value());
3435}
3436
3437
3438String* JSRegExp::Pattern() {
3439 ASSERT(this->data()->IsFixedArray());
3440 Object* data = this->data();
3441 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3442 return pattern;
3443}
3444
3445
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003446Object* JSRegExp::DataAt(int index) {
3447 ASSERT(TypeTag() != NOT_COMPILED);
3448 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003449}
3450
3451
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003452void JSRegExp::SetDataAt(int index, Object* value) {
3453 ASSERT(TypeTag() != NOT_COMPILED);
3454 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3455 FixedArray::cast(data())->set(index, value);
3456}
3457
3458
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003459JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003460 if (map()->has_fast_elements()) {
3461 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3462 elements()->map() == Heap::fixed_cow_array_map());
3463 return FAST_ELEMENTS;
3464 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003465 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003466 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003467 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3468 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003469 ASSERT(array->IsDictionary());
3470 return DICTIONARY_ELEMENTS;
3471 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003472 if (array->IsExternalArray()) {
3473 switch (array->map()->instance_type()) {
3474 case EXTERNAL_BYTE_ARRAY_TYPE:
3475 return EXTERNAL_BYTE_ELEMENTS;
3476 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3477 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3478 case EXTERNAL_SHORT_ARRAY_TYPE:
3479 return EXTERNAL_SHORT_ELEMENTS;
3480 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3481 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3482 case EXTERNAL_INT_ARRAY_TYPE:
3483 return EXTERNAL_INT_ELEMENTS;
3484 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3485 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3486 default:
3487 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3488 return EXTERNAL_FLOAT_ELEMENTS;
3489 }
3490 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003491 ASSERT(array->IsPixelArray());
3492 return PIXEL_ELEMENTS;
3493}
3494
3495
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003496bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003497 return GetElementsKind() == FAST_ELEMENTS;
3498}
3499
3500
3501bool JSObject::HasDictionaryElements() {
3502 return GetElementsKind() == DICTIONARY_ELEMENTS;
3503}
3504
3505
3506bool JSObject::HasPixelElements() {
3507 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508}
3509
3510
ager@chromium.org3811b432009-10-28 14:53:37 +00003511bool JSObject::HasExternalArrayElements() {
3512 return (HasExternalByteElements() ||
3513 HasExternalUnsignedByteElements() ||
3514 HasExternalShortElements() ||
3515 HasExternalUnsignedShortElements() ||
3516 HasExternalIntElements() ||
3517 HasExternalUnsignedIntElements() ||
3518 HasExternalFloatElements());
3519}
3520
3521
3522bool JSObject::HasExternalByteElements() {
3523 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3524}
3525
3526
3527bool JSObject::HasExternalUnsignedByteElements() {
3528 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3529}
3530
3531
3532bool JSObject::HasExternalShortElements() {
3533 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3534}
3535
3536
3537bool JSObject::HasExternalUnsignedShortElements() {
3538 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3539}
3540
3541
3542bool JSObject::HasExternalIntElements() {
3543 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3544}
3545
3546
3547bool JSObject::HasExternalUnsignedIntElements() {
3548 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3549}
3550
3551
3552bool JSObject::HasExternalFloatElements() {
3553 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3554}
3555
3556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003557bool JSObject::HasNamedInterceptor() {
3558 return map()->has_named_interceptor();
3559}
3560
3561
3562bool JSObject::HasIndexedInterceptor() {
3563 return map()->has_indexed_interceptor();
3564}
3565
3566
ager@chromium.org5c838252010-02-19 08:53:10 +00003567bool JSObject::AllowsSetElementsLength() {
3568 bool result = elements()->IsFixedArray();
3569 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3570 return result;
3571}
3572
3573
lrn@chromium.org303ada72010-10-27 09:33:13 +00003574MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003575 ASSERT(HasFastElements());
3576 FixedArray* elems = FixedArray::cast(elements());
3577 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003578 Object* writable_elems;
3579 { MaybeObject* maybe_writable_elems =
3580 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3581 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3582 return maybe_writable_elems;
3583 }
3584 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003585 set_elements(FixedArray::cast(writable_elems));
3586 Counters::cow_arrays_converted.Increment();
3587 return writable_elems;
3588}
3589
3590
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003591StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003592 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003593 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003594}
3595
3596
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003597NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003598 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003599 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003600}
3601
3602
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003603bool String::IsHashFieldComputed(uint32_t field) {
3604 return (field & kHashNotComputedMask) == 0;
3605}
3606
3607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003609 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610}
3611
3612
3613uint32_t String::Hash() {
3614 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003615 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003616 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003617 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003618 return ComputeAndSetHash();
3619}
3620
3621
ager@chromium.org7c537e22008-10-16 08:43:32 +00003622StringHasher::StringHasher(int length)
3623 : length_(length),
3624 raw_running_hash_(0),
3625 array_index_(0),
3626 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3627 is_first_char_(true),
3628 is_valid_(true) { }
3629
3630
3631bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003632 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003633}
3634
3635
3636void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003637 // Use the Jenkins one-at-a-time hash function to update the hash
3638 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003639 raw_running_hash_ += c;
3640 raw_running_hash_ += (raw_running_hash_ << 10);
3641 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003642 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003643 if (is_array_index_) {
3644 if (c < '0' || c > '9') {
3645 is_array_index_ = false;
3646 } else {
3647 int d = c - '0';
3648 if (is_first_char_) {
3649 is_first_char_ = false;
3650 if (c == '0' && length_ > 1) {
3651 is_array_index_ = false;
3652 return;
3653 }
3654 }
3655 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3656 is_array_index_ = false;
3657 } else {
3658 array_index_ = array_index_ * 10 + d;
3659 }
3660 }
3661 }
3662}
3663
3664
3665void StringHasher::AddCharacterNoIndex(uc32 c) {
3666 ASSERT(!is_array_index());
3667 raw_running_hash_ += c;
3668 raw_running_hash_ += (raw_running_hash_ << 10);
3669 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3670}
3671
3672
3673uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003674 // Get the calculated raw hash value and do some more bit ops to distribute
3675 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003676 uint32_t result = raw_running_hash_;
3677 result += (result << 3);
3678 result ^= (result >> 11);
3679 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003680 if (result == 0) {
3681 result = 27;
3682 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003683 return result;
3684}
3685
3686
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003687bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003688 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003689 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3690 return false;
3691 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003692 return SlowAsArrayIndex(index);
3693}
3694
3695
3696Object* JSObject::GetPrototype() {
3697 return JSObject::cast(this)->map()->prototype();
3698}
3699
3700
3701PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3702 return GetPropertyAttributeWithReceiver(this, key);
3703}
3704
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003705// TODO(504): this may be useful in other places too where JSGlobalProxy
3706// is used.
3707Object* JSObject::BypassGlobalProxy() {
3708 if (IsJSGlobalProxy()) {
3709 Object* proto = GetPrototype();
3710 if (proto->IsNull()) return Heap::undefined_value();
3711 ASSERT(proto->IsJSGlobalObject());
3712 return proto;
3713 }
3714 return this;
3715}
3716
3717
3718bool JSObject::HasHiddenPropertiesObject() {
3719 ASSERT(!IsJSGlobalProxy());
3720 return GetPropertyAttributePostInterceptor(this,
3721 Heap::hidden_symbol(),
3722 false) != ABSENT;
3723}
3724
3725
3726Object* JSObject::GetHiddenPropertiesObject() {
3727 ASSERT(!IsJSGlobalProxy());
3728 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003729 // You can't install a getter on a property indexed by the hidden symbol,
3730 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3731 // object.
3732 Object* result =
3733 GetLocalPropertyPostInterceptor(this,
3734 Heap::hidden_symbol(),
3735 &attributes)->ToObjectUnchecked();
3736 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003737}
3738
3739
lrn@chromium.org303ada72010-10-27 09:33:13 +00003740MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003741 ASSERT(!IsJSGlobalProxy());
3742 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3743 hidden_obj,
3744 DONT_ENUM);
3745}
3746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003747
3748bool JSObject::HasElement(uint32_t index) {
3749 return HasElementWithReceiver(this, index);
3750}
3751
3752
3753bool AccessorInfo::all_can_read() {
3754 return BooleanBit::get(flag(), kAllCanReadBit);
3755}
3756
3757
3758void AccessorInfo::set_all_can_read(bool value) {
3759 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3760}
3761
3762
3763bool AccessorInfo::all_can_write() {
3764 return BooleanBit::get(flag(), kAllCanWriteBit);
3765}
3766
3767
3768void AccessorInfo::set_all_can_write(bool value) {
3769 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3770}
3771
3772
ager@chromium.org870a0b62008-11-04 11:43:05 +00003773bool AccessorInfo::prohibits_overwriting() {
3774 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3775}
3776
3777
3778void AccessorInfo::set_prohibits_overwriting(bool value) {
3779 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3780}
3781
3782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003783PropertyAttributes AccessorInfo::property_attributes() {
3784 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3785}
3786
3787
3788void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3789 ASSERT(AttributesField::is_valid(attributes));
3790 int rest_value = flag()->value() & ~AttributesField::mask();
3791 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3792}
3793
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003794template<typename Shape, typename Key>
3795void Dictionary<Shape, Key>::SetEntry(int entry,
3796 Object* key,
3797 Object* value,
3798 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003799 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003800 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003801 AssertNoAllocation no_gc;
3802 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003803 FixedArray::set(index, key, mode);
3804 FixedArray::set(index+1, value, mode);
3805 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806}
3807
3808
3809void Map::ClearCodeCache() {
3810 // No write barrier is needed since empty_fixed_array is not in new space.
3811 // Please note this function is used during marking:
3812 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003813 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3814 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815}
3816
3817
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003818void JSArray::EnsureSize(int required_size) {
3819 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003820 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003821 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3822 if (elts->length() < required_size) {
3823 // Doubling in size would be overkill, but leave some slack to avoid
3824 // constantly growing.
3825 Expand(required_size + (required_size >> 3));
3826 // It's a performance benefit to keep a frequently used array in new-space.
3827 } else if (!Heap::new_space()->Contains(elts) &&
3828 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3829 // Expand will allocate a new backing store in new space even if the size
3830 // we asked for isn't larger than what we had before.
3831 Expand(required_size);
3832 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003833}
3834
3835
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003836void JSArray::set_length(Smi* length) {
3837 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3838}
3839
3840
ager@chromium.org7c537e22008-10-16 08:43:32 +00003841void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003842 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003843 set_elements(storage);
3844}
3845
3846
lrn@chromium.org303ada72010-10-27 09:33:13 +00003847MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003848 if (length() == 0) return this;
3849 return Heap::CopyFixedArray(this);
3850}
3851
3852
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003853int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3854 return map->instance_size();
3855}
3856
3857
3858void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3859 v->VisitExternalReference(
3860 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3861}
3862
3863
3864template<typename StaticVisitor>
3865void Proxy::ProxyIterateBody() {
3866 StaticVisitor::VisitExternalReference(
3867 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3868}
3869
3870
3871void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3872 typedef v8::String::ExternalAsciiStringResource Resource;
3873 v->VisitExternalAsciiString(
3874 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3875}
3876
3877
3878template<typename StaticVisitor>
3879void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3880 typedef v8::String::ExternalAsciiStringResource Resource;
3881 StaticVisitor::VisitExternalAsciiString(
3882 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3883}
3884
3885
3886void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3887 typedef v8::String::ExternalStringResource Resource;
3888 v->VisitExternalTwoByteString(
3889 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3890}
3891
3892
3893template<typename StaticVisitor>
3894void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3895 typedef v8::String::ExternalStringResource Resource;
3896 StaticVisitor::VisitExternalTwoByteString(
3897 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3898}
3899
3900#define SLOT_ADDR(obj, offset) \
3901 reinterpret_cast<Object**>((obj)->address() + offset)
3902
3903template<int start_offset, int end_offset, int size>
3904void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3905 HeapObject* obj,
3906 ObjectVisitor* v) {
3907 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3908}
3909
3910
3911template<int start_offset>
3912void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3913 int object_size,
3914 ObjectVisitor* v) {
3915 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3916}
3917
3918#undef SLOT_ADDR
3919
3920
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003921#undef CAST_ACCESSOR
3922#undef INT_ACCESSORS
3923#undef SMI_ACCESSORS
3924#undef ACCESSORS
3925#undef FIELD_ADDR
3926#undef READ_FIELD
3927#undef WRITE_FIELD
3928#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003929#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003930#undef READ_MEMADDR_FIELD
3931#undef WRITE_MEMADDR_FIELD
3932#undef READ_DOUBLE_FIELD
3933#undef WRITE_DOUBLE_FIELD
3934#undef READ_INT_FIELD
3935#undef WRITE_INT_FIELD
3936#undef READ_SHORT_FIELD
3937#undef WRITE_SHORT_FIELD
3938#undef READ_BYTE_FIELD
3939#undef WRITE_BYTE_FIELD
3940
3941
3942} } // namespace v8::internal
3943
3944#endif // V8_OBJECTS_INL_H_