blob: 01073ca7b08bd272520e1b1009d266a671411e7e [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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000333bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000334 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000335 HeapObject::cast(this)->map()->instance_type() ==
336 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000337}
338
339
ager@chromium.org3811b432009-10-28 14:53:37 +0000340bool Object::IsExternalArray() {
341 if (!Object::IsHeapObject())
342 return false;
343 InstanceType instance_type =
344 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000345 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
346 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000347}
348
349
350bool Object::IsExternalByteArray() {
351 return Object::IsHeapObject() &&
352 HeapObject::cast(this)->map()->instance_type() ==
353 EXTERNAL_BYTE_ARRAY_TYPE;
354}
355
356
357bool Object::IsExternalUnsignedByteArray() {
358 return Object::IsHeapObject() &&
359 HeapObject::cast(this)->map()->instance_type() ==
360 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
361}
362
363
364bool Object::IsExternalShortArray() {
365 return Object::IsHeapObject() &&
366 HeapObject::cast(this)->map()->instance_type() ==
367 EXTERNAL_SHORT_ARRAY_TYPE;
368}
369
370
371bool Object::IsExternalUnsignedShortArray() {
372 return Object::IsHeapObject() &&
373 HeapObject::cast(this)->map()->instance_type() ==
374 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
375}
376
377
378bool Object::IsExternalIntArray() {
379 return Object::IsHeapObject() &&
380 HeapObject::cast(this)->map()->instance_type() ==
381 EXTERNAL_INT_ARRAY_TYPE;
382}
383
384
385bool Object::IsExternalUnsignedIntArray() {
386 return Object::IsHeapObject() &&
387 HeapObject::cast(this)->map()->instance_type() ==
388 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
389}
390
391
392bool Object::IsExternalFloatArray() {
393 return Object::IsHeapObject() &&
394 HeapObject::cast(this)->map()->instance_type() ==
395 EXTERNAL_FLOAT_ARRAY_TYPE;
396}
397
398
lrn@chromium.org303ada72010-10-27 09:33:13 +0000399bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400 return HAS_FAILURE_TAG(this);
401}
402
403
lrn@chromium.org303ada72010-10-27 09:33:13 +0000404bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405 return HAS_FAILURE_TAG(this)
406 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
407}
408
409
lrn@chromium.org303ada72010-10-27 09:33:13 +0000410bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000411 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000412 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000413}
414
415
lrn@chromium.org303ada72010-10-27 09:33:13 +0000416bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417 return this == Failure::Exception();
418}
419
420
lrn@chromium.org303ada72010-10-27 09:33:13 +0000421bool MaybeObject::IsTheHole() {
422 return this == Heap::the_hole_value();
423}
424
425
426Failure* Failure::cast(MaybeObject* obj) {
427 ASSERT(HAS_FAILURE_TAG(obj));
428 return reinterpret_cast<Failure*>(obj);
429}
430
431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000432bool Object::IsJSObject() {
433 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000434 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000435}
436
437
ager@chromium.org32912102009-01-16 10:38:43 +0000438bool Object::IsJSContextExtensionObject() {
439 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000440 && (HeapObject::cast(this)->map()->instance_type() ==
441 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000442}
443
444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445bool Object::IsMap() {
446 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000447 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000448}
449
450
451bool Object::IsFixedArray() {
452 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000453 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454}
455
456
457bool Object::IsDescriptorArray() {
458 return IsFixedArray();
459}
460
461
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000462bool Object::IsDeoptimizationInputData() {
463 // Must be a fixed array.
464 if (!IsFixedArray()) return false;
465
466 // There's no sure way to detect the difference between a fixed array and
467 // a deoptimization data array. Since this is used for asserts we can
468 // check that the length is zero or else the fixed size plus a multiple of
469 // the entry size.
470 int length = FixedArray::cast(this)->length();
471 if (length == 0) return true;
472
473 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
474 return length >= 0 &&
475 length % DeoptimizationInputData::kDeoptEntrySize == 0;
476}
477
478
479bool Object::IsDeoptimizationOutputData() {
480 if (!IsFixedArray()) return false;
481 // There's actually no way to see the difference between a fixed array and
482 // a deoptimization data array. Since this is used for asserts we can check
483 // that the length is plausible though.
484 if (FixedArray::cast(this)->length() % 2 != 0) return false;
485 return true;
486}
487
488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489bool Object::IsContext() {
490 return Object::IsHeapObject()
491 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000492 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493 HeapObject::cast(this)->map() == Heap::global_context_map());
494}
495
496
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000497bool Object::IsCatchContext() {
498 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000499 && HeapObject::cast(this)->map() == Heap::catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000500}
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503bool Object::IsGlobalContext() {
504 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000505 && HeapObject::cast(this)->map() == Heap::global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000506}
507
508
509bool Object::IsJSFunction() {
510 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000511 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000512}
513
514
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000515template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516 return obj->IsJSFunction();
517}
518
519
520bool Object::IsCode() {
521 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000522 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000523}
524
525
526bool Object::IsOddball() {
527 return Object::IsHeapObject()
528 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
529}
530
531
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000532bool Object::IsJSGlobalPropertyCell() {
533 return Object::IsHeapObject()
534 && HeapObject::cast(this)->map()->instance_type()
535 == JS_GLOBAL_PROPERTY_CELL_TYPE;
536}
537
538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000539bool Object::IsSharedFunctionInfo() {
540 return Object::IsHeapObject() &&
541 (HeapObject::cast(this)->map()->instance_type() ==
542 SHARED_FUNCTION_INFO_TYPE);
543}
544
545
546bool Object::IsJSValue() {
547 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000548 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
549}
550
551
552bool Object::IsJSMessageObject() {
553 return Object::IsHeapObject()
554 && (HeapObject::cast(this)->map()->instance_type() ==
555 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000556}
557
558
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000559bool Object::IsStringWrapper() {
560 return IsJSValue() && JSValue::cast(this)->value()->IsString();
561}
562
563
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564bool Object::IsProxy() {
565 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000566 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567}
568
569
570bool Object::IsBoolean() {
571 return IsTrue() || IsFalse();
572}
573
574
575bool Object::IsJSArray() {
576 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000577 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578}
579
580
ager@chromium.org236ad962008-09-25 09:45:57 +0000581bool Object::IsJSRegExp() {
582 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000583 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000584}
585
586
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000587template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588 return obj->IsJSArray();
589}
590
591
592bool Object::IsHashTable() {
593 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000594 && HeapObject::cast(this)->map() == Heap::hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595}
596
597
598bool Object::IsDictionary() {
599 return IsHashTable() && this != Heap::symbol_table();
600}
601
602
603bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000604 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605}
606
607
ager@chromium.orgac091b72010-05-05 07:34:42 +0000608bool Object::IsJSFunctionResultCache() {
609 if (!IsFixedArray()) return false;
610 FixedArray* self = FixedArray::cast(this);
611 int length = self->length();
612 if (length < JSFunctionResultCache::kEntriesIndex) return false;
613 if ((length - JSFunctionResultCache::kEntriesIndex)
614 % JSFunctionResultCache::kEntrySize != 0) {
615 return false;
616 }
617#ifdef DEBUG
618 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
619#endif
620 return true;
621}
622
623
ricow@chromium.org65fae842010-08-25 15:26:24 +0000624bool Object::IsNormalizedMapCache() {
625 if (!IsFixedArray()) return false;
626 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
627 return false;
628 }
629#ifdef DEBUG
630 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
631#endif
632 return true;
633}
634
635
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000636bool Object::IsCompilationCacheTable() {
637 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000638}
639
640
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000641bool Object::IsCodeCacheHashTable() {
642 return IsHashTable();
643}
644
645
ager@chromium.org236ad962008-09-25 09:45:57 +0000646bool Object::IsMapCache() {
647 return IsHashTable();
648}
649
650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651bool Object::IsPrimitive() {
652 return IsOddball() || IsNumber() || IsString();
653}
654
655
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000656bool Object::IsJSGlobalProxy() {
657 bool result = IsHeapObject() &&
658 (HeapObject::cast(this)->map()->instance_type() ==
659 JS_GLOBAL_PROXY_TYPE);
660 ASSERT(!result || IsAccessCheckNeeded());
661 return result;
662}
663
664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000666 if (!IsHeapObject()) return false;
667
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000668 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000669 return type == JS_GLOBAL_OBJECT_TYPE ||
670 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671}
672
673
674bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000675 return IsHeapObject() &&
676 (HeapObject::cast(this)->map()->instance_type() ==
677 JS_GLOBAL_OBJECT_TYPE);
678}
679
680
681bool Object::IsJSBuiltinsObject() {
682 return IsHeapObject() &&
683 (HeapObject::cast(this)->map()->instance_type() ==
684 JS_BUILTINS_OBJECT_TYPE);
685}
686
687
688bool Object::IsUndetectableObject() {
689 return IsHeapObject()
690 && HeapObject::cast(this)->map()->is_undetectable();
691}
692
693
694bool Object::IsAccessCheckNeeded() {
695 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000696 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000697}
698
699
700bool Object::IsStruct() {
701 if (!IsHeapObject()) return false;
702 switch (HeapObject::cast(this)->map()->instance_type()) {
703#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
704 STRUCT_LIST(MAKE_STRUCT_CASE)
705#undef MAKE_STRUCT_CASE
706 default: return false;
707 }
708}
709
710
711#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
712 bool Object::Is##Name() { \
713 return Object::IsHeapObject() \
714 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
715 }
716 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
717#undef MAKE_STRUCT_PREDICATE
718
719
720bool Object::IsUndefined() {
721 return this == Heap::undefined_value();
722}
723
724
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725bool Object::IsNull() {
726 return this == Heap::null_value();
727}
728
729
730bool Object::IsTrue() {
731 return this == Heap::true_value();
732}
733
734
735bool Object::IsFalse() {
736 return this == Heap::false_value();
737}
738
739
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000740bool Object::IsArgumentsMarker() {
741 return this == Heap::arguments_marker();
742}
743
744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745double Object::Number() {
746 ASSERT(IsNumber());
747 return IsSmi()
748 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
749 : reinterpret_cast<HeapNumber*>(this)->value();
750}
751
752
753
lrn@chromium.org303ada72010-10-27 09:33:13 +0000754MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755 if (IsSmi()) return this;
756 if (IsHeapNumber()) {
757 double value = HeapNumber::cast(this)->value();
758 int int_value = FastD2I(value);
759 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
760 return Smi::FromInt(int_value);
761 }
762 }
763 return Failure::Exception();
764}
765
766
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000767bool Object::HasSpecificClassOf(String* name) {
768 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
769}
770
771
lrn@chromium.org303ada72010-10-27 09:33:13 +0000772MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000773 // GetElement can trigger a getter which can cause allocation.
774 // This was not always the case. This ASSERT is here to catch
775 // leftover incorrect uses.
776 ASSERT(Heap::IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777 return GetElementWithReceiver(this, index);
778}
779
780
lrn@chromium.org303ada72010-10-27 09:33:13 +0000781Object* Object::GetElementNoExceptionThrown(uint32_t index) {
782 MaybeObject* maybe = GetElementWithReceiver(this, index);
783 ASSERT(!maybe->IsFailure());
784 Object* result = NULL; // Initialization to please compiler.
785 maybe->ToObject(&result);
786 return result;
787}
788
789
790MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000791 PropertyAttributes attributes;
792 return GetPropertyWithReceiver(this, key, &attributes);
793}
794
795
lrn@chromium.org303ada72010-10-27 09:33:13 +0000796MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000797 return GetPropertyWithReceiver(this, key, attributes);
798}
799
800
801#define FIELD_ADDR(p, offset) \
802 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
803
804#define READ_FIELD(p, offset) \
805 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
806
807#define WRITE_FIELD(p, offset, value) \
808 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
809
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000810
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000811#define WRITE_BARRIER(object, offset) \
812 Heap::RecordWrite(object->address(), offset);
813
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000814// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000815// write due to the assert validating the written value.
816#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
817 if (mode == UPDATE_WRITE_BARRIER) { \
818 Heap::RecordWrite(object->address(), offset); \
819 } else { \
820 ASSERT(mode == SKIP_WRITE_BARRIER); \
821 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000822 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000823 Page::FromAddress(object->address())-> \
824 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000825 }
826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000827#define READ_DOUBLE_FIELD(p, offset) \
828 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
829
830#define WRITE_DOUBLE_FIELD(p, offset, value) \
831 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
832
833#define READ_INT_FIELD(p, offset) \
834 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
835
836#define WRITE_INT_FIELD(p, offset, value) \
837 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
838
ager@chromium.org3e875802009-06-29 08:26:34 +0000839#define READ_INTPTR_FIELD(p, offset) \
840 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
841
842#define WRITE_INTPTR_FIELD(p, offset, value) \
843 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
844
ager@chromium.org7c537e22008-10-16 08:43:32 +0000845#define READ_UINT32_FIELD(p, offset) \
846 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
847
848#define WRITE_UINT32_FIELD(p, offset, value) \
849 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
850
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851#define READ_SHORT_FIELD(p, offset) \
852 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
853
854#define WRITE_SHORT_FIELD(p, offset, value) \
855 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
856
857#define READ_BYTE_FIELD(p, offset) \
858 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
859
860#define WRITE_BYTE_FIELD(p, offset, value) \
861 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
862
863
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000864Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
865 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000866}
867
868
869int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000870 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000871}
872
873
874Smi* Smi::FromInt(int value) {
875 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000876 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000877 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000878 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000879 return reinterpret_cast<Smi*>(tagged_value);
880}
881
882
883Smi* Smi::FromIntptr(intptr_t value) {
884 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000885 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
886 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887}
888
889
890Failure::Type Failure::type() const {
891 return static_cast<Type>(value() & kFailureTypeTagMask);
892}
893
894
895bool Failure::IsInternalError() const {
896 return type() == INTERNAL_ERROR;
897}
898
899
900bool Failure::IsOutOfMemoryException() const {
901 return type() == OUT_OF_MEMORY_EXCEPTION;
902}
903
904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905AllocationSpace Failure::allocation_space() const {
906 ASSERT_EQ(RETRY_AFTER_GC, type());
907 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
908 & kSpaceTagMask);
909}
910
911
912Failure* Failure::InternalError() {
913 return Construct(INTERNAL_ERROR);
914}
915
916
917Failure* Failure::Exception() {
918 return Construct(EXCEPTION);
919}
920
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922Failure* Failure::OutOfMemoryException() {
923 return Construct(OUT_OF_MEMORY_EXCEPTION);
924}
925
926
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000927intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000928 return static_cast<intptr_t>(
929 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930}
931
932
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000933Failure* Failure::RetryAfterGC() {
934 return RetryAfterGC(NEW_SPACE);
935}
936
937
938Failure* Failure::RetryAfterGC(AllocationSpace space) {
939 ASSERT((space & ~kSpaceTagMask) == 0);
940 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000941}
942
943
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000944Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000945 uintptr_t info =
946 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000947 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000948 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000949}
950
951
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000952bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000953#ifdef DEBUG
954 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
955#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956
957#ifdef V8_TARGET_ARCH_X64
958 // To be representable as a long smi, the value must be a 32-bit integer.
959 bool result = (value == static_cast<int32_t>(value));
960#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000961 // To be representable as an tagged small integer, the two
962 // most-significant bits of 'value' must be either 00 or 11 due to
963 // sign-extension. To check this we add 01 to the two
964 // most-significant bits, and check if the most-significant bit is 0
965 //
966 // CAUTION: The original code below:
967 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
968 // may lead to incorrect results according to the C language spec, and
969 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
970 // compiler may produce undefined results in case of signed integer
971 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000972 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000973#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000974 ASSERT(result == in_range);
975 return result;
976}
977
978
kasper.lund7276f142008-07-30 08:49:36 +0000979MapWord MapWord::FromMap(Map* map) {
980 return MapWord(reinterpret_cast<uintptr_t>(map));
981}
982
983
984Map* MapWord::ToMap() {
985 return reinterpret_cast<Map*>(value_);
986}
987
988
989bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000990 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000991}
992
993
994MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000995 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
996 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000997}
998
999
1000HeapObject* MapWord::ToForwardingAddress() {
1001 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001002 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001003}
1004
1005
1006bool MapWord::IsMarked() {
1007 return (value_ & kMarkingMask) == 0;
1008}
1009
1010
1011void MapWord::SetMark() {
1012 value_ &= ~kMarkingMask;
1013}
1014
1015
1016void MapWord::ClearMark() {
1017 value_ |= kMarkingMask;
1018}
1019
1020
1021bool MapWord::IsOverflowed() {
1022 return (value_ & kOverflowMask) != 0;
1023}
1024
1025
1026void MapWord::SetOverflow() {
1027 value_ |= kOverflowMask;
1028}
1029
1030
1031void MapWord::ClearOverflow() {
1032 value_ &= ~kOverflowMask;
1033}
1034
1035
1036MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1037 // Offset is the distance in live bytes from the first live object in the
1038 // same page. The offset between two objects in the same page should not
1039 // exceed the object area size of a page.
1040 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1041
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001042 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001043 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1044
1045 Page* map_page = Page::FromAddress(map_address);
1046 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1047
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001048 uintptr_t map_page_offset =
1049 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001050
1051 uintptr_t encoding =
1052 (compact_offset << kForwardingOffsetShift) |
1053 (map_page_offset << kMapPageOffsetShift) |
1054 (map_page->mc_page_index << kMapPageIndexShift);
1055 return MapWord(encoding);
1056}
1057
1058
1059Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001060 int map_page_index =
1061 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001062 ASSERT_MAP_PAGE_INDEX(map_page_index);
1063
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001064 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001065 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1066 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001067
1068 return (map_space->PageAddress(map_page_index) + map_page_offset);
1069}
1070
1071
1072int MapWord::DecodeOffset() {
1073 // The offset field is represented in the kForwardingOffsetBits
1074 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001075 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1076 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1077 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001078}
1079
1080
1081MapWord MapWord::FromEncodedAddress(Address address) {
1082 return MapWord(reinterpret_cast<uintptr_t>(address));
1083}
1084
1085
1086Address MapWord::ToEncodedAddress() {
1087 return reinterpret_cast<Address>(value_);
1088}
1089
1090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091#ifdef DEBUG
1092void HeapObject::VerifyObjectField(int offset) {
1093 VerifyPointer(READ_FIELD(this, offset));
1094}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001095
1096void HeapObject::VerifySmiField(int offset) {
1097 ASSERT(READ_FIELD(this, offset)->IsSmi());
1098}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001099#endif
1100
1101
1102Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001103 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
1107void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001108 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001109}
1110
1111
kasper.lund7276f142008-07-30 08:49:36 +00001112MapWord HeapObject::map_word() {
1113 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1114}
1115
1116
1117void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001118 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001119 // here.
1120 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1121}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001122
1123
1124HeapObject* HeapObject::FromAddress(Address address) {
1125 ASSERT_TAG_ALIGNED(address);
1126 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1127}
1128
1129
1130Address HeapObject::address() {
1131 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1132}
1133
1134
1135int HeapObject::Size() {
1136 return SizeFromMap(map());
1137}
1138
1139
1140void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1141 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1142 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1143}
1144
1145
1146void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1147 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1148}
1149
1150
kasper.lund7276f142008-07-30 08:49:36 +00001151bool HeapObject::IsMarked() {
1152 return map_word().IsMarked();
1153}
1154
1155
1156void HeapObject::SetMark() {
1157 ASSERT(!IsMarked());
1158 MapWord first_word = map_word();
1159 first_word.SetMark();
1160 set_map_word(first_word);
1161}
1162
1163
1164void HeapObject::ClearMark() {
1165 ASSERT(IsMarked());
1166 MapWord first_word = map_word();
1167 first_word.ClearMark();
1168 set_map_word(first_word);
1169}
1170
1171
1172bool HeapObject::IsOverflowed() {
1173 return map_word().IsOverflowed();
1174}
1175
1176
1177void HeapObject::SetOverflow() {
1178 MapWord first_word = map_word();
1179 first_word.SetOverflow();
1180 set_map_word(first_word);
1181}
1182
1183
1184void HeapObject::ClearOverflow() {
1185 ASSERT(IsOverflowed());
1186 MapWord first_word = map_word();
1187 first_word.ClearOverflow();
1188 set_map_word(first_word);
1189}
1190
1191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192double HeapNumber::value() {
1193 return READ_DOUBLE_FIELD(this, kValueOffset);
1194}
1195
1196
1197void HeapNumber::set_value(double value) {
1198 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1199}
1200
1201
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001202int HeapNumber::get_exponent() {
1203 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1204 kExponentShift) - kExponentBias;
1205}
1206
1207
1208int HeapNumber::get_sign() {
1209 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1210}
1211
1212
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001213ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001214
1215
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001216HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001217 Object* array = READ_FIELD(this, kElementsOffset);
1218 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001219 ASSERT(array->IsFixedArray() || 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.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001229 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001230 WRITE_FIELD(this, kElementsOffset, value);
1231 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1232}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233
1234
1235void JSObject::initialize_properties() {
1236 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1237 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1238}
1239
1240
1241void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001242 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001243 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1244 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1245}
1246
1247
lrn@chromium.org303ada72010-10-27 09:33:13 +00001248MaybeObject* JSObject::ResetElements() {
1249 Object* obj;
1250 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1251 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1252 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001253 set_map(Map::cast(obj));
1254 initialize_elements();
1255 return this;
1256}
1257
1258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001259ACCESSORS(Oddball, to_string, String, kToStringOffset)
1260ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1261
1262
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001263Object* JSGlobalPropertyCell::value() {
1264 return READ_FIELD(this, kValueOffset);
1265}
1266
1267
1268void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1269 // The write barrier is not used for global property cells.
1270 ASSERT(!val->IsJSGlobalPropertyCell());
1271 WRITE_FIELD(this, kValueOffset, val);
1272}
1273
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001274
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001276 InstanceType type = map()->instance_type();
1277 // Check for the most common kind of JavaScript object before
1278 // falling into the generic switch. This speeds up the internal
1279 // field operations considerably on average.
1280 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1281 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001282 case JS_GLOBAL_PROXY_TYPE:
1283 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001284 case JS_GLOBAL_OBJECT_TYPE:
1285 return JSGlobalObject::kSize;
1286 case JS_BUILTINS_OBJECT_TYPE:
1287 return JSBuiltinsObject::kSize;
1288 case JS_FUNCTION_TYPE:
1289 return JSFunction::kSize;
1290 case JS_VALUE_TYPE:
1291 return JSValue::kSize;
1292 case JS_ARRAY_TYPE:
1293 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001294 case JS_REGEXP_TYPE:
1295 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001296 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001298 case JS_MESSAGE_OBJECT_TYPE:
1299 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001300 default:
1301 UNREACHABLE();
1302 return 0;
1303 }
1304}
1305
1306
1307int JSObject::GetInternalFieldCount() {
1308 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001309 // Make sure to adjust for the number of in-object properties. These
1310 // properties do contribute to the size, but are not internal fields.
1311 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1312 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001313}
1314
1315
1316Object* JSObject::GetInternalField(int index) {
1317 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001318 // Internal objects do follow immediately after the header, whereas in-object
1319 // properties are at the end of the object. Therefore there is no need
1320 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001321 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1322}
1323
1324
1325void JSObject::SetInternalField(int index, Object* value) {
1326 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001327 // Internal objects do follow immediately after the header, whereas in-object
1328 // properties are at the end of the object. Therefore there is no need
1329 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001330 int offset = GetHeaderSize() + (kPointerSize * index);
1331 WRITE_FIELD(this, offset, value);
1332 WRITE_BARRIER(this, offset);
1333}
1334
1335
ager@chromium.org7c537e22008-10-16 08:43:32 +00001336// Access fast-case object properties at index. The use of these routines
1337// is needed to correctly distinguish between properties stored in-object and
1338// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001339Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001340 // Adjust for the number of properties stored in the object.
1341 index -= map()->inobject_properties();
1342 if (index < 0) {
1343 int offset = map()->instance_size() + (index * kPointerSize);
1344 return READ_FIELD(this, offset);
1345 } else {
1346 ASSERT(index < properties()->length());
1347 return properties()->get(index);
1348 }
1349}
1350
1351
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001352Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001353 // Adjust for the number of properties stored in the object.
1354 index -= map()->inobject_properties();
1355 if (index < 0) {
1356 int offset = map()->instance_size() + (index * kPointerSize);
1357 WRITE_FIELD(this, offset, value);
1358 WRITE_BARRIER(this, offset);
1359 } else {
1360 ASSERT(index < properties()->length());
1361 properties()->set(index, value);
1362 }
1363 return value;
1364}
1365
1366
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001367Object* JSObject::InObjectPropertyAt(int index) {
1368 // Adjust for the number of properties stored in the object.
1369 index -= map()->inobject_properties();
1370 ASSERT(index < 0);
1371 int offset = map()->instance_size() + (index * kPointerSize);
1372 return READ_FIELD(this, offset);
1373}
1374
1375
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001376Object* JSObject::InObjectPropertyAtPut(int index,
1377 Object* value,
1378 WriteBarrierMode mode) {
1379 // Adjust for the number of properties stored in the object.
1380 index -= map()->inobject_properties();
1381 ASSERT(index < 0);
1382 int offset = map()->instance_size() + (index * kPointerSize);
1383 WRITE_FIELD(this, offset, value);
1384 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1385 return value;
1386}
1387
1388
1389
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001390void JSObject::InitializeBody(int object_size, Object* value) {
1391 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001392 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001393 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394 }
1395}
1396
1397
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001398bool JSObject::HasFastProperties() {
1399 return !properties()->IsDictionary();
1400}
1401
1402
1403int JSObject::MaxFastProperties() {
1404 // Allow extra fast properties if the object has more than
1405 // kMaxFastProperties in-object properties. When this is the case,
1406 // it is very unlikely that the object is being used as a dictionary
1407 // and there is a good chance that allowing more map transitions
1408 // will be worth it.
1409 return Max(map()->inobject_properties(), kMaxFastProperties);
1410}
1411
1412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001414 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001415 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001416 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 }
1418}
1419
1420
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001421bool Object::ToArrayIndex(uint32_t* index) {
1422 if (IsSmi()) {
1423 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001424 if (value < 0) return false;
1425 *index = value;
1426 return true;
1427 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001428 if (IsHeapNumber()) {
1429 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 uint32_t uint_value = static_cast<uint32_t>(value);
1431 if (value == static_cast<double>(uint_value)) {
1432 *index = uint_value;
1433 return true;
1434 }
1435 }
1436 return false;
1437}
1438
1439
1440bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1441 if (!this->IsJSValue()) return false;
1442
1443 JSValue* js_value = JSValue::cast(this);
1444 if (!js_value->value()->IsString()) return false;
1445
1446 String* str = String::cast(js_value->value());
1447 if (index >= (uint32_t)str->length()) return false;
1448
1449 return true;
1450}
1451
1452
1453Object* FixedArray::get(int index) {
1454 ASSERT(index >= 0 && index < this->length());
1455 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1456}
1457
1458
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001459void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001460 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001461 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1462 int offset = kHeaderSize + index * kPointerSize;
1463 WRITE_FIELD(this, offset, value);
1464}
1465
1466
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001467void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001468 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469 ASSERT(index >= 0 && index < this->length());
1470 int offset = kHeaderSize + index * kPointerSize;
1471 WRITE_FIELD(this, offset, value);
1472 WRITE_BARRIER(this, offset);
1473}
1474
1475
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001476WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1478 return UPDATE_WRITE_BARRIER;
1479}
1480
1481
1482void FixedArray::set(int index,
1483 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001484 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001485 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001486 ASSERT(index >= 0 && index < this->length());
1487 int offset = kHeaderSize + index * kPointerSize;
1488 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001489 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001490}
1491
1492
1493void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001494 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001495 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001496 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001497 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1498}
1499
1500
1501void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001502 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001503 ASSERT(index >= 0 && index < this->length());
1504 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1505 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1506 Heap::undefined_value());
1507}
1508
1509
ager@chromium.org236ad962008-09-25 09:45:57 +00001510void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001511 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001512 ASSERT(index >= 0 && index < this->length());
1513 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1514 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1515}
1516
1517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001518void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001519 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001520 ASSERT(index >= 0 && index < this->length());
1521 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1522 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1523}
1524
1525
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001526void FixedArray::set_unchecked(int index, Smi* value) {
1527 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1528 int offset = kHeaderSize + index * kPointerSize;
1529 WRITE_FIELD(this, offset, value);
1530}
1531
1532
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001533void FixedArray::set_unchecked(int index,
1534 Object* value,
1535 WriteBarrierMode mode) {
1536 int offset = kHeaderSize + index * kPointerSize;
1537 WRITE_FIELD(this, offset, value);
1538 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1539}
1540
1541
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001542void FixedArray::set_null_unchecked(int index) {
1543 ASSERT(index >= 0 && index < this->length());
1544 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1545 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1546}
1547
1548
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001549Object** FixedArray::data_start() {
1550 return HeapObject::RawField(this, kHeaderSize);
1551}
1552
1553
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001554bool DescriptorArray::IsEmpty() {
1555 ASSERT(this == Heap::empty_descriptor_array() ||
1556 this->length() > 2);
1557 return this == Heap::empty_descriptor_array();
1558}
1559
1560
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1562 Object* tmp = array->get(first);
1563 fast_set(array, first, array->get(second));
1564 fast_set(array, second, tmp);
1565}
1566
1567
1568int DescriptorArray::Search(String* name) {
1569 SLOW_ASSERT(IsSortedNoDuplicates());
1570
1571 // Check for empty descriptor array.
1572 int nof = number_of_descriptors();
1573 if (nof == 0) return kNotFound;
1574
1575 // Fast case: do linear search for small arrays.
1576 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001577 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001578 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 }
1580
1581 // Slow case: perform binary search.
1582 return BinarySearch(name, 0, nof - 1);
1583}
1584
1585
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001586int DescriptorArray::SearchWithCache(String* name) {
1587 int number = DescriptorLookupCache::Lookup(this, name);
1588 if (number == DescriptorLookupCache::kAbsent) {
1589 number = Search(name);
1590 DescriptorLookupCache::Update(this, name, number);
1591 }
1592 return number;
1593}
1594
1595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596String* DescriptorArray::GetKey(int descriptor_number) {
1597 ASSERT(descriptor_number < number_of_descriptors());
1598 return String::cast(get(ToKeyIndex(descriptor_number)));
1599}
1600
1601
1602Object* DescriptorArray::GetValue(int descriptor_number) {
1603 ASSERT(descriptor_number < number_of_descriptors());
1604 return GetContentArray()->get(ToValueIndex(descriptor_number));
1605}
1606
1607
1608Smi* DescriptorArray::GetDetails(int descriptor_number) {
1609 ASSERT(descriptor_number < number_of_descriptors());
1610 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1611}
1612
1613
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001614PropertyType DescriptorArray::GetType(int descriptor_number) {
1615 ASSERT(descriptor_number < number_of_descriptors());
1616 return PropertyDetails(GetDetails(descriptor_number)).type();
1617}
1618
1619
1620int DescriptorArray::GetFieldIndex(int descriptor_number) {
1621 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1622}
1623
1624
1625JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1626 return JSFunction::cast(GetValue(descriptor_number));
1627}
1628
1629
1630Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1631 ASSERT(GetType(descriptor_number) == CALLBACKS);
1632 return GetValue(descriptor_number);
1633}
1634
1635
1636AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1637 ASSERT(GetType(descriptor_number) == CALLBACKS);
1638 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1639 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1640}
1641
1642
1643bool DescriptorArray::IsProperty(int descriptor_number) {
1644 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1645}
1646
1647
1648bool DescriptorArray::IsTransition(int descriptor_number) {
1649 PropertyType t = GetType(descriptor_number);
1650 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1651}
1652
1653
1654bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1655 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1656}
1657
1658
1659bool DescriptorArray::IsDontEnum(int descriptor_number) {
1660 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1661}
1662
1663
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001664void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1665 desc->Init(GetKey(descriptor_number),
1666 GetValue(descriptor_number),
1667 GetDetails(descriptor_number));
1668}
1669
1670
1671void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1672 // Range check.
1673 ASSERT(descriptor_number < number_of_descriptors());
1674
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001675 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001676 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1677 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1678
1679 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1680 FixedArray* content_array = GetContentArray();
1681 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1682 fast_set(content_array, ToDetailsIndex(descriptor_number),
1683 desc->GetDetails().AsSmi());
1684}
1685
1686
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001687void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1688 Descriptor desc;
1689 src->Get(src_index, &desc);
1690 Set(index, &desc);
1691}
1692
1693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694void DescriptorArray::Swap(int first, int second) {
1695 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1696 FixedArray* content_array = GetContentArray();
1697 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1698 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1699}
1700
1701
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001702bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001703 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001704 if (!max_index_object->IsSmi()) return false;
1705 return 0 !=
1706 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1707}
1708
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001709uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001711 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712 if (!max_index_object->IsSmi()) return 0;
1713 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1714 return value >> kRequiresSlowElementsTagSize;
1715}
1716
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001717void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001718 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001719}
1720
1721
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722// ------------------------------------
1723// Cast operations
1724
1725
1726CAST_ACCESSOR(FixedArray)
1727CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001728CAST_ACCESSOR(DeoptimizationInputData)
1729CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001731CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001732CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001733CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001734CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001735CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736CAST_ACCESSOR(String)
1737CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001738CAST_ACCESSOR(SeqAsciiString)
1739CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001740CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741CAST_ACCESSOR(ExternalString)
1742CAST_ACCESSOR(ExternalAsciiString)
1743CAST_ACCESSOR(ExternalTwoByteString)
1744CAST_ACCESSOR(JSObject)
1745CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001746CAST_ACCESSOR(HeapObject)
1747CAST_ACCESSOR(HeapNumber)
1748CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001749CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001750CAST_ACCESSOR(SharedFunctionInfo)
1751CAST_ACCESSOR(Map)
1752CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001753CAST_ACCESSOR(GlobalObject)
1754CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001755CAST_ACCESSOR(JSGlobalObject)
1756CAST_ACCESSOR(JSBuiltinsObject)
1757CAST_ACCESSOR(Code)
1758CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001759CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760CAST_ACCESSOR(Proxy)
1761CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001762CAST_ACCESSOR(ExternalArray)
1763CAST_ACCESSOR(ExternalByteArray)
1764CAST_ACCESSOR(ExternalUnsignedByteArray)
1765CAST_ACCESSOR(ExternalShortArray)
1766CAST_ACCESSOR(ExternalUnsignedShortArray)
1767CAST_ACCESSOR(ExternalIntArray)
1768CAST_ACCESSOR(ExternalUnsignedIntArray)
1769CAST_ACCESSOR(ExternalFloatArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001770CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771CAST_ACCESSOR(Struct)
1772
1773
1774#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1775 STRUCT_LIST(MAKE_STRUCT_CAST)
1776#undef MAKE_STRUCT_CAST
1777
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001778
1779template <typename Shape, typename Key>
1780HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 ASSERT(obj->IsHashTable());
1782 return reinterpret_cast<HashTable*>(obj);
1783}
1784
1785
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001786SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1787SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1788
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001789INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790
1791
ager@chromium.orgac091b72010-05-05 07:34:42 +00001792SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001793
1794
1795uint32_t String::hash_field() {
1796 return READ_UINT32_FIELD(this, kHashFieldOffset);
1797}
1798
1799
1800void String::set_hash_field(uint32_t value) {
1801 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001802#if V8_HOST_ARCH_64_BIT
1803 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1804#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001805}
1806
1807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808bool String::Equals(String* other) {
1809 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001810 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1811 return false;
1812 }
1813 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814}
1815
1816
lrn@chromium.org303ada72010-10-27 09:33:13 +00001817MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001818 if (!StringShape(this).IsCons()) return this;
1819 ConsString* cons = ConsString::cast(this);
1820 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001821 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822}
1823
1824
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001825String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001826 MaybeObject* flat = TryFlatten(pretenure);
1827 Object* successfully_flattened;
1828 if (flat->ToObject(&successfully_flattened)) {
1829 return String::cast(successfully_flattened);
1830 }
1831 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001832}
1833
1834
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001835uint16_t String::Get(int index) {
1836 ASSERT(index >= 0 && index < length());
1837 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001838 case kSeqStringTag | kAsciiStringTag:
1839 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1840 case kSeqStringTag | kTwoByteStringTag:
1841 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1842 case kConsStringTag | kAsciiStringTag:
1843 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001844 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001845 case kExternalStringTag | kAsciiStringTag:
1846 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1847 case kExternalStringTag | kTwoByteStringTag:
1848 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 default:
1850 break;
1851 }
1852
1853 UNREACHABLE();
1854 return 0;
1855}
1856
1857
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001858void String::Set(int index, uint16_t value) {
1859 ASSERT(index >= 0 && index < length());
1860 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001861
ager@chromium.org5ec48922009-05-05 07:25:34 +00001862 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001863 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1864 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001865}
1866
1867
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001868bool String::IsFlat() {
1869 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001870 case kConsStringTag: {
1871 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001872 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001873 return second->length() == 0;
1874 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001875 default:
1876 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877 }
1878}
1879
1880
ager@chromium.org7c537e22008-10-16 08:43:32 +00001881uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001882 ASSERT(index >= 0 && index < length());
1883 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1884}
1885
1886
ager@chromium.org7c537e22008-10-16 08:43:32 +00001887void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1889 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1890 static_cast<byte>(value));
1891}
1892
1893
ager@chromium.org7c537e22008-10-16 08:43:32 +00001894Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895 return FIELD_ADDR(this, kHeaderSize);
1896}
1897
1898
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001899char* SeqAsciiString::GetChars() {
1900 return reinterpret_cast<char*>(GetCharsAddress());
1901}
1902
1903
ager@chromium.org7c537e22008-10-16 08:43:32 +00001904Address SeqTwoByteString::GetCharsAddress() {
1905 return FIELD_ADDR(this, kHeaderSize);
1906}
1907
1908
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001909uc16* SeqTwoByteString::GetChars() {
1910 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1911}
1912
1913
ager@chromium.org7c537e22008-10-16 08:43:32 +00001914uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001915 ASSERT(index >= 0 && index < length());
1916 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1917}
1918
1919
ager@chromium.org7c537e22008-10-16 08:43:32 +00001920void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001921 ASSERT(index >= 0 && index < length());
1922 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1923}
1924
1925
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001926int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001927 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928}
1929
1930
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001931int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001932 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001933}
1934
1935
ager@chromium.org870a0b62008-11-04 11:43:05 +00001936String* ConsString::first() {
1937 return String::cast(READ_FIELD(this, kFirstOffset));
1938}
1939
1940
1941Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942 return READ_FIELD(this, kFirstOffset);
1943}
1944
1945
ager@chromium.org870a0b62008-11-04 11:43:05 +00001946void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001948 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949}
1950
1951
ager@chromium.org870a0b62008-11-04 11:43:05 +00001952String* ConsString::second() {
1953 return String::cast(READ_FIELD(this, kSecondOffset));
1954}
1955
1956
1957Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001958 return READ_FIELD(this, kSecondOffset);
1959}
1960
1961
ager@chromium.org870a0b62008-11-04 11:43:05 +00001962void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001964 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965}
1966
1967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001968ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1969 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1970}
1971
1972
1973void ExternalAsciiString::set_resource(
1974 ExternalAsciiString::Resource* resource) {
1975 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1976}
1977
1978
1979ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1980 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1981}
1982
1983
1984void ExternalTwoByteString::set_resource(
1985 ExternalTwoByteString::Resource* resource) {
1986 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1987}
1988
1989
ager@chromium.orgac091b72010-05-05 07:34:42 +00001990void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001991 set_finger_index(kEntriesIndex);
1992 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001993}
1994
1995
1996void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001997 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00001998 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001999 MemsetPointer(entries_start,
2000 Heap::the_hole_value(),
2001 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002002 MakeZeroSize();
2003}
2004
2005
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002006int JSFunctionResultCache::size() {
2007 return Smi::cast(get(kCacheSizeIndex))->value();
2008}
2009
2010
2011void JSFunctionResultCache::set_size(int size) {
2012 set(kCacheSizeIndex, Smi::FromInt(size));
2013}
2014
2015
2016int JSFunctionResultCache::finger_index() {
2017 return Smi::cast(get(kFingerIndex))->value();
2018}
2019
2020
2021void JSFunctionResultCache::set_finger_index(int finger_index) {
2022 set(kFingerIndex, Smi::FromInt(finger_index));
2023}
2024
2025
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026byte ByteArray::get(int index) {
2027 ASSERT(index >= 0 && index < this->length());
2028 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2029}
2030
2031
2032void ByteArray::set(int index, byte value) {
2033 ASSERT(index >= 0 && index < this->length());
2034 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2035}
2036
2037
2038int ByteArray::get_int(int index) {
2039 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2040 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2041}
2042
2043
2044ByteArray* ByteArray::FromDataStartAddress(Address address) {
2045 ASSERT_TAG_ALIGNED(address);
2046 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2047}
2048
2049
2050Address ByteArray::GetDataStartAddress() {
2051 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2052}
2053
2054
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002055uint8_t* ExternalPixelArray::external_pixel_pointer() {
2056 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002057}
2058
2059
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002060uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002061 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002062 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002063 return ptr[index];
2064}
2065
2066
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002067void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002068 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002069 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002070 ptr[index] = value;
2071}
2072
2073
ager@chromium.org3811b432009-10-28 14:53:37 +00002074void* ExternalArray::external_pointer() {
2075 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2076 return reinterpret_cast<void*>(ptr);
2077}
2078
2079
2080void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2081 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2082 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2083}
2084
2085
2086int8_t ExternalByteArray::get(int index) {
2087 ASSERT((index >= 0) && (index < this->length()));
2088 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2089 return ptr[index];
2090}
2091
2092
2093void ExternalByteArray::set(int index, int8_t value) {
2094 ASSERT((index >= 0) && (index < this->length()));
2095 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2096 ptr[index] = value;
2097}
2098
2099
2100uint8_t ExternalUnsignedByteArray::get(int index) {
2101 ASSERT((index >= 0) && (index < this->length()));
2102 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2103 return ptr[index];
2104}
2105
2106
2107void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2108 ASSERT((index >= 0) && (index < this->length()));
2109 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2110 ptr[index] = value;
2111}
2112
2113
2114int16_t ExternalShortArray::get(int index) {
2115 ASSERT((index >= 0) && (index < this->length()));
2116 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2117 return ptr[index];
2118}
2119
2120
2121void ExternalShortArray::set(int index, int16_t value) {
2122 ASSERT((index >= 0) && (index < this->length()));
2123 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2124 ptr[index] = value;
2125}
2126
2127
2128uint16_t ExternalUnsignedShortArray::get(int index) {
2129 ASSERT((index >= 0) && (index < this->length()));
2130 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2131 return ptr[index];
2132}
2133
2134
2135void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2136 ASSERT((index >= 0) && (index < this->length()));
2137 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2138 ptr[index] = value;
2139}
2140
2141
2142int32_t ExternalIntArray::get(int index) {
2143 ASSERT((index >= 0) && (index < this->length()));
2144 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2145 return ptr[index];
2146}
2147
2148
2149void ExternalIntArray::set(int index, int32_t value) {
2150 ASSERT((index >= 0) && (index < this->length()));
2151 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2152 ptr[index] = value;
2153}
2154
2155
2156uint32_t ExternalUnsignedIntArray::get(int index) {
2157 ASSERT((index >= 0) && (index < this->length()));
2158 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2159 return ptr[index];
2160}
2161
2162
2163void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2164 ASSERT((index >= 0) && (index < this->length()));
2165 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2166 ptr[index] = value;
2167}
2168
2169
2170float ExternalFloatArray::get(int index) {
2171 ASSERT((index >= 0) && (index < this->length()));
2172 float* ptr = static_cast<float*>(external_pointer());
2173 return ptr[index];
2174}
2175
2176
2177void ExternalFloatArray::set(int index, float value) {
2178 ASSERT((index >= 0) && (index < this->length()));
2179 float* ptr = static_cast<float*>(external_pointer());
2180 ptr[index] = value;
2181}
2182
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002183
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002184int Map::visitor_id() {
2185 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2186}
2187
2188
2189void Map::set_visitor_id(int id) {
2190 ASSERT(0 <= id && id < 256);
2191 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2192}
2193
ager@chromium.org3811b432009-10-28 14:53:37 +00002194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002196 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2197}
2198
2199
2200int Map::inobject_properties() {
2201 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202}
2203
2204
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002205int Map::pre_allocated_property_fields() {
2206 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2207}
2208
2209
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002210int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002211 int instance_size = map->instance_size();
2212 if (instance_size != kVariableSizeSentinel) return instance_size;
2213 // We can ignore the "symbol" bit becase it is only set for symbols
2214 // and implies a string type.
2215 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002216 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002217 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002218 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002219 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002220 if (instance_type == ASCII_STRING_TYPE) {
2221 return SeqAsciiString::SizeFor(
2222 reinterpret_cast<SeqAsciiString*>(this)->length());
2223 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002224 if (instance_type == BYTE_ARRAY_TYPE) {
2225 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2226 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002227 if (instance_type == STRING_TYPE) {
2228 return SeqTwoByteString::SizeFor(
2229 reinterpret_cast<SeqTwoByteString*>(this)->length());
2230 }
2231 ASSERT(instance_type == CODE_TYPE);
2232 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002233}
2234
2235
2236void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002237 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002238 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239 ASSERT(0 <= value && value < 256);
2240 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2241}
2242
2243
ager@chromium.org7c537e22008-10-16 08:43:32 +00002244void Map::set_inobject_properties(int value) {
2245 ASSERT(0 <= value && value < 256);
2246 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2247}
2248
2249
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002250void Map::set_pre_allocated_property_fields(int value) {
2251 ASSERT(0 <= value && value < 256);
2252 WRITE_BYTE_FIELD(this,
2253 kPreAllocatedPropertyFieldsOffset,
2254 static_cast<byte>(value));
2255}
2256
2257
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258InstanceType Map::instance_type() {
2259 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2260}
2261
2262
2263void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2265}
2266
2267
2268int Map::unused_property_fields() {
2269 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2270}
2271
2272
2273void Map::set_unused_property_fields(int value) {
2274 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2275}
2276
2277
2278byte Map::bit_field() {
2279 return READ_BYTE_FIELD(this, kBitFieldOffset);
2280}
2281
2282
2283void Map::set_bit_field(byte value) {
2284 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2285}
2286
2287
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002288byte Map::bit_field2() {
2289 return READ_BYTE_FIELD(this, kBitField2Offset);
2290}
2291
2292
2293void Map::set_bit_field2(byte value) {
2294 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2295}
2296
2297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298void Map::set_non_instance_prototype(bool value) {
2299 if (value) {
2300 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2301 } else {
2302 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2303 }
2304}
2305
2306
2307bool Map::has_non_instance_prototype() {
2308 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2309}
2310
2311
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002312void Map::set_function_with_prototype(bool value) {
2313 if (value) {
2314 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2315 } else {
2316 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2317 }
2318}
2319
2320
2321bool Map::function_with_prototype() {
2322 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2323}
2324
2325
ager@chromium.org870a0b62008-11-04 11:43:05 +00002326void Map::set_is_access_check_needed(bool access_check_needed) {
2327 if (access_check_needed) {
2328 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2329 } else {
2330 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2331 }
2332}
2333
2334
2335bool Map::is_access_check_needed() {
2336 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2337}
2338
2339
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002340void Map::set_is_extensible(bool value) {
2341 if (value) {
2342 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2343 } else {
2344 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2345 }
2346}
2347
2348bool Map::is_extensible() {
2349 return ((1 << kIsExtensible) & bit_field2()) != 0;
2350}
2351
2352
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002353void Map::set_attached_to_shared_function_info(bool value) {
2354 if (value) {
2355 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2356 } else {
2357 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2358 }
2359}
2360
2361bool Map::attached_to_shared_function_info() {
2362 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2363}
2364
2365
2366void Map::set_is_shared(bool value) {
2367 if (value) {
2368 set_bit_field2(bit_field2() | (1 << kIsShared));
2369 } else {
2370 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2371 }
2372}
2373
2374bool Map::is_shared() {
2375 return ((1 << kIsShared) & bit_field2()) != 0;
2376}
2377
2378
2379JSFunction* Map::unchecked_constructor() {
2380 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2381}
2382
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384Code::Flags Code::flags() {
2385 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2386}
2387
2388
2389void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002390 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002392 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2393 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394 ExtractArgumentsCountFromFlags(flags) >= 0);
2395 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2396}
2397
2398
2399Code::Kind Code::kind() {
2400 return ExtractKindFromFlags(flags());
2401}
2402
2403
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002404InLoopFlag Code::ic_in_loop() {
2405 return ExtractICInLoopFromFlags(flags());
2406}
2407
2408
kasper.lund7276f142008-07-30 08:49:36 +00002409InlineCacheState Code::ic_state() {
2410 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 // Only allow uninitialized or debugger states for non-IC code
2412 // objects. This is used in the debugger to determine whether or not
2413 // a call to code object has been replaced with a debug break call.
2414 ASSERT(is_inline_cache_stub() ||
2415 result == UNINITIALIZED ||
2416 result == DEBUG_BREAK ||
2417 result == DEBUG_PREPARE_STEP_IN);
2418 return result;
2419}
2420
2421
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002422Code::ExtraICState Code::extra_ic_state() {
2423 ASSERT(is_inline_cache_stub());
2424 return ExtractExtraICStateFromFlags(flags());
2425}
2426
2427
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002429 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430 return ExtractTypeFromFlags(flags());
2431}
2432
2433
2434int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002435 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436 return ExtractArgumentsCountFromFlags(flags());
2437}
2438
2439
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002440int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002441 ASSERT(kind() == STUB ||
2442 kind() == BINARY_OP_IC ||
2443 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2444 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002445 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002446}
2447
2448
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002449void Code::set_major_key(int major) {
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);
kasper.lund7276f142008-07-30 08:49:36 +00002454 ASSERT(0 <= major && major < 256);
2455 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002456}
2457
2458
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459bool Code::optimizable() {
2460 ASSERT(kind() == FUNCTION);
2461 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2462}
2463
2464
2465void Code::set_optimizable(bool value) {
2466 ASSERT(kind() == FUNCTION);
2467 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2468}
2469
2470
2471bool Code::has_deoptimization_support() {
2472 ASSERT(kind() == FUNCTION);
2473 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2474}
2475
2476
2477void Code::set_has_deoptimization_support(bool value) {
2478 ASSERT(kind() == FUNCTION);
2479 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2480}
2481
2482
2483int Code::allow_osr_at_loop_nesting_level() {
2484 ASSERT(kind() == FUNCTION);
2485 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2486}
2487
2488
2489void Code::set_allow_osr_at_loop_nesting_level(int level) {
2490 ASSERT(kind() == FUNCTION);
2491 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2492 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2493}
2494
2495
2496unsigned Code::stack_slots() {
2497 ASSERT(kind() == OPTIMIZED_FUNCTION);
2498 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2499}
2500
2501
2502void Code::set_stack_slots(unsigned slots) {
2503 ASSERT(kind() == OPTIMIZED_FUNCTION);
2504 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2505}
2506
2507
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002508unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002510 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511}
2512
2513
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002514void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 ASSERT(kind() == OPTIMIZED_FUNCTION);
2516 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002517 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518}
2519
2520
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002521unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002522 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002523 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002524}
2525
2526
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002527void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002528 ASSERT(kind() == FUNCTION);
2529 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002530 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531}
2532
2533
2534CheckType Code::check_type() {
2535 ASSERT(is_call_stub() || is_keyed_call_stub());
2536 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2537 return static_cast<CheckType>(type);
2538}
2539
2540
2541void Code::set_check_type(CheckType value) {
2542 ASSERT(is_call_stub() || is_keyed_call_stub());
2543 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2544}
2545
2546
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002547ExternalArrayType Code::external_array_type() {
2548 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2549 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2550 return static_cast<ExternalArrayType>(type);
2551}
2552
2553
2554void Code::set_external_array_type(ExternalArrayType value) {
2555 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2556 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2557}
2558
2559
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560byte Code::binary_op_type() {
2561 ASSERT(is_binary_op_stub());
2562 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2563}
2564
2565
2566void Code::set_binary_op_type(byte value) {
2567 ASSERT(is_binary_op_stub());
2568 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2569}
2570
2571
2572byte Code::type_recording_binary_op_type() {
2573 ASSERT(is_type_recording_binary_op_stub());
2574 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2575}
2576
2577
2578void Code::set_type_recording_binary_op_type(byte value) {
2579 ASSERT(is_type_recording_binary_op_stub());
2580 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2581}
2582
2583
2584byte Code::type_recording_binary_op_result_type() {
2585 ASSERT(is_type_recording_binary_op_stub());
2586 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2587}
2588
2589
2590void Code::set_type_recording_binary_op_result_type(byte value) {
2591 ASSERT(is_type_recording_binary_op_stub());
2592 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2593}
2594
2595
2596byte Code::compare_state() {
2597 ASSERT(is_compare_ic_stub());
2598 return READ_BYTE_FIELD(this, kCompareStateOffset);
2599}
2600
2601
2602void Code::set_compare_state(byte value) {
2603 ASSERT(is_compare_ic_stub());
2604 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2605}
2606
2607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608bool Code::is_inline_cache_stub() {
2609 Kind kind = this->kind();
2610 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2611}
2612
2613
2614Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002615 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002616 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002617 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002618 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002619 int argc,
2620 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002621 // Extra IC state is only allowed for monomorphic call IC stubs
2622 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002623 ASSERT(extra_ic_state == kNoExtraICState ||
2624 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002625 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002626 (kind == STORE_IC) ||
2627 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002628 // Compute the bit mask.
2629 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002630 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002631 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002633 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002634 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002635 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636 // Cast to flags and validate result before returning it.
2637 Flags result = static_cast<Flags>(bits);
2638 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002639 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002640 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002642 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002643 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2644 return result;
2645}
2646
2647
2648Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2649 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002650 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002651 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002652 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002654 return ComputeFlags(
2655 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002656}
2657
2658
2659Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2660 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2661 return static_cast<Kind>(bits);
2662}
2663
2664
kasper.lund7276f142008-07-30 08:49:36 +00002665InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2666 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667 return static_cast<InlineCacheState>(bits);
2668}
2669
2670
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002671Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2672 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2673 return static_cast<ExtraICState>(bits);
2674}
2675
2676
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002677InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2678 int bits = (flags & kFlagsICInLoopMask);
2679 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2680}
2681
2682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002683PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2684 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2685 return static_cast<PropertyType>(bits);
2686}
2687
2688
2689int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2690 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2691}
2692
2693
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002694InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2695 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2696 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2697}
2698
2699
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2701 int bits = flags & ~kFlagsTypeMask;
2702 return static_cast<Flags>(bits);
2703}
2704
2705
ager@chromium.org8bb60582008-12-11 12:02:20 +00002706Code* Code::GetCodeFromTargetAddress(Address address) {
2707 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2708 // GetCodeFromTargetAddress might be called when marking objects during mark
2709 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2710 // Code::cast. Code::cast does not work when the object's map is
2711 // marked.
2712 Code* result = reinterpret_cast<Code*>(code);
2713 return result;
2714}
2715
2716
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002717Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2718 return HeapObject::
2719 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2720}
2721
2722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002723Object* Map::prototype() {
2724 return READ_FIELD(this, kPrototypeOffset);
2725}
2726
2727
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002728void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002729 ASSERT(value->IsNull() || value->IsJSObject());
2730 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002731 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732}
2733
2734
lrn@chromium.org303ada72010-10-27 09:33:13 +00002735MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002736 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002737 Object* obj;
2738 { MaybeObject* maybe_obj = CopyDropTransitions();
2739 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2740 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002741 Map* new_map = Map::cast(obj);
2742 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002743 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002744 return new_map;
2745}
2746
2747
lrn@chromium.org303ada72010-10-27 09:33:13 +00002748MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002749 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002750 Object* obj;
2751 { MaybeObject* maybe_obj = CopyDropTransitions();
2752 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2753 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002754 Map* new_map = Map::cast(obj);
2755 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002756 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002757 return new_map;
2758}
2759
2760
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002761MaybeObject* Map::NewExternalArrayElementsMap() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002762 // TODO(danno): Special case empty object map (or most common case)
2763 // to return a pre-canned pixel array map.
2764 Object* obj;
2765 { MaybeObject* maybe_obj = CopyDropTransitions();
2766 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2767 }
2768 Map* new_map = Map::cast(obj);
2769 new_map->set_has_fast_elements(false);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002770 new_map->set_has_external_array_elements(true);
2771 Counters::map_to_external_array_elements.Increment();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002772 return new_map;
2773}
2774
2775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776ACCESSORS(Map, instance_descriptors, DescriptorArray,
2777 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002778ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779ACCESSORS(Map, constructor, Object, kConstructorOffset)
2780
2781ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2782ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002783ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784
2785ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2786ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002787ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002788
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002789ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002790
2791ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2792ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2793ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2794ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2795ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2796
2797ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2798ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2799ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2800
2801ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2802ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2803ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2804ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2805ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2806ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2807
2808ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2809ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2810
2811ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2812ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2813
2814ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2815ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002816ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2817 kPropertyAccessorsOffset)
2818ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2819 kPrototypeTemplateOffset)
2820ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2821ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2822 kNamedPropertyHandlerOffset)
2823ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2824 kIndexedPropertyHandlerOffset)
2825ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2826 kInstanceTemplateOffset)
2827ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2828ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002829ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2830 kInstanceCallHandlerOffset)
2831ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2832 kAccessCheckInfoOffset)
2833ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2834
2835ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002836ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2837 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002838
2839ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2840ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2841
2842ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2843
2844ACCESSORS(Script, source, Object, kSourceOffset)
2845ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002846ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002847ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2848ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002849ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002850ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002851ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2852ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002853ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002854ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002855ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002856ACCESSORS(Script, eval_from_instructions_offset, Smi,
2857 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002859#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002860ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2861ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2862ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2863ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2864
2865ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2866ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2867ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2868ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002869#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002870
2871ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002872ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002873ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002874ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2875 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002876ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002877ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2878ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002879ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002880ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2881 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882
2883BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2884 kHiddenPrototypeBit)
2885BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2886BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2887 kNeedsAccessCheckBit)
2888BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2889 kIsExpressionBit)
2890BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2891 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002892BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002893 has_only_simple_this_property_assignments,
2894 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002895BOOL_ACCESSORS(SharedFunctionInfo,
2896 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002897 try_full_codegen,
2898 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002899BOOL_ACCESSORS(SharedFunctionInfo,
2900 compiler_hints,
2901 allows_lazy_compilation,
2902 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002903
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002904
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002905#if V8_HOST_ARCH_32_BIT
2906SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2907SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002908 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002909SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002910 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002911SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2912SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002914SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2915SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002916 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002917SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002918 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002919SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002920 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002922#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002923
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002924#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002925 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002926 int holder::name() { \
2927 int value = READ_INT_FIELD(this, offset); \
2928 ASSERT(kHeapObjectTag == 1); \
2929 ASSERT((value & kHeapObjectTag) == 0); \
2930 return value >> 1; \
2931 } \
2932 void holder::set_##name(int value) { \
2933 ASSERT(kHeapObjectTag == 1); \
2934 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2935 (value & 0xC0000000) == 0x000000000); \
2936 WRITE_INT_FIELD(this, \
2937 offset, \
2938 (value << 1) & ~kHeapObjectTag); \
2939 }
2940
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002941#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2942 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002943 INT_ACCESSORS(holder, name, offset)
2944
2945
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002946PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002947PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2948 formal_parameter_count,
2949 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002950
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002951PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2952 expected_nof_properties,
2953 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002954PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2955
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002956PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
2957PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2958 start_position_and_type,
2959 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002960
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002961PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2962 function_token_position,
2963 kFunctionTokenPositionOffset)
2964PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2965 compiler_hints,
2966 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002967
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002968PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2969 this_property_assignments_count,
2970 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002971PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002972#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002974
2975int SharedFunctionInfo::construction_count() {
2976 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2977}
2978
2979
2980void SharedFunctionInfo::set_construction_count(int value) {
2981 ASSERT(0 <= value && value < 256);
2982 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2983}
2984
2985
2986bool SharedFunctionInfo::live_objects_may_exist() {
2987 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2988}
2989
2990
2991void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2992 if (value) {
2993 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2994 } else {
2995 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2996 }
2997}
2998
2999
3000bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
3001 return initial_map() != Heap::undefined_value();
3002}
3003
3004
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005bool SharedFunctionInfo::optimization_disabled() {
3006 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3007}
3008
3009
3010void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3011 set_compiler_hints(BooleanBit::set(compiler_hints(),
3012 kOptimizationDisabled,
3013 disable));
3014 // If disabling optimizations we reflect that in the code object so
3015 // it will not be counted as optimizable code.
3016 if ((code()->kind() == Code::FUNCTION) && disable) {
3017 code()->set_optimizable(false);
3018 }
3019}
3020
3021
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003022bool SharedFunctionInfo::strict_mode() {
3023 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3024}
3025
3026
3027void SharedFunctionInfo::set_strict_mode(bool value) {
3028 set_compiler_hints(BooleanBit::set(compiler_hints(),
3029 kStrictModeFunction,
3030 value));
3031}
3032
3033
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003034ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3035ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3036
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003037bool Script::HasValidSource() {
3038 Object* src = this->source();
3039 if (!src->IsString()) return true;
3040 String* src_str = String::cast(src);
3041 if (!StringShape(src_str).IsExternal()) return true;
3042 if (src_str->IsAsciiRepresentation()) {
3043 return ExternalAsciiString::cast(src)->resource() != NULL;
3044 } else if (src_str->IsTwoByteRepresentation()) {
3045 return ExternalTwoByteString::cast(src)->resource() != NULL;
3046 }
3047 return true;
3048}
3049
3050
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003051void SharedFunctionInfo::DontAdaptArguments() {
3052 ASSERT(code()->kind() == Code::BUILTIN);
3053 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3054}
3055
3056
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057int SharedFunctionInfo::start_position() {
3058 return start_position_and_type() >> kStartPositionShift;
3059}
3060
3061
3062void SharedFunctionInfo::set_start_position(int start_position) {
3063 set_start_position_and_type((start_position << kStartPositionShift)
3064 | (start_position_and_type() & ~kStartPositionMask));
3065}
3066
3067
3068Code* SharedFunctionInfo::code() {
3069 return Code::cast(READ_FIELD(this, kCodeOffset));
3070}
3071
3072
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003073Code* SharedFunctionInfo::unchecked_code() {
3074 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3075}
3076
3077
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003078void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003079 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003080 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081}
3082
3083
ager@chromium.orgb5737492010-07-15 09:29:43 +00003084SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3085 return reinterpret_cast<SerializedScopeInfo*>(
3086 READ_FIELD(this, kScopeInfoOffset));
3087}
3088
3089
3090void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3091 WriteBarrierMode mode) {
3092 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3093 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3094}
3095
3096
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097Smi* SharedFunctionInfo::deopt_counter() {
3098 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3099}
3100
3101
3102void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3103 WRITE_FIELD(this, kDeoptCounterOffset, value);
3104}
3105
3106
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003107bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003108 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003109}
3110
3111
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003112bool SharedFunctionInfo::IsApiFunction() {
3113 return function_data()->IsFunctionTemplateInfo();
3114}
3115
3116
3117FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3118 ASSERT(IsApiFunction());
3119 return FunctionTemplateInfo::cast(function_data());
3120}
3121
3122
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003123bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003124 return function_data()->IsSmi();
3125}
3126
3127
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003128BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3129 ASSERT(HasBuiltinFunctionId());
3130 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003131}
3132
3133
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003134int SharedFunctionInfo::code_age() {
3135 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3136}
3137
3138
3139void SharedFunctionInfo::set_code_age(int code_age) {
3140 set_compiler_hints(compiler_hints() |
3141 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3142}
3143
3144
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003145bool SharedFunctionInfo::has_deoptimization_support() {
3146 Code* code = this->code();
3147 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3148}
3149
3150
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003151bool JSFunction::IsBuiltin() {
3152 return context()->global()->IsJSBuiltinsObject();
3153}
3154
3155
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156bool JSFunction::NeedsArgumentsAdaption() {
3157 return shared()->formal_parameter_count() !=
3158 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3159}
3160
3161
3162bool JSFunction::IsOptimized() {
3163 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3164}
3165
3166
3167bool JSFunction::IsMarkedForLazyRecompilation() {
3168 return code() == Builtins::builtin(Builtins::LazyRecompile);
3169}
3170
3171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003172Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003173 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003174}
3175
3176
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003177Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003178 return reinterpret_cast<Code*>(
3179 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003180}
3181
3182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003183void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003184 // Skip the write barrier because code is never in new space.
3185 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003186 Address entry = value->entry();
3187 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003188}
3189
3190
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191void JSFunction::ReplaceCode(Code* code) {
3192 bool was_optimized = IsOptimized();
3193 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3194
3195 set_code(code);
3196
3197 // Add/remove the function from the list of optimized functions for this
3198 // context based on the state change.
3199 if (!was_optimized && is_optimized) {
3200 context()->global_context()->AddOptimizedFunction(this);
3201 }
3202 if (was_optimized && !is_optimized) {
3203 context()->global_context()->RemoveOptimizedFunction(this);
3204 }
3205}
3206
3207
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208Context* JSFunction::context() {
3209 return Context::cast(READ_FIELD(this, kContextOffset));
3210}
3211
3212
3213Object* JSFunction::unchecked_context() {
3214 return READ_FIELD(this, kContextOffset);
3215}
3216
3217
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003218SharedFunctionInfo* JSFunction::unchecked_shared() {
3219 return reinterpret_cast<SharedFunctionInfo*>(
3220 READ_FIELD(this, kSharedFunctionInfoOffset));
3221}
3222
3223
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003224void JSFunction::set_context(Object* value) {
3225 ASSERT(value == Heap::undefined_value() || value->IsContext());
3226 WRITE_FIELD(this, kContextOffset, value);
3227 WRITE_BARRIER(this, kContextOffset);
3228}
3229
3230ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3231 kPrototypeOrInitialMapOffset)
3232
3233
3234Map* JSFunction::initial_map() {
3235 return Map::cast(prototype_or_initial_map());
3236}
3237
3238
3239void JSFunction::set_initial_map(Map* value) {
3240 set_prototype_or_initial_map(value);
3241}
3242
3243
3244bool JSFunction::has_initial_map() {
3245 return prototype_or_initial_map()->IsMap();
3246}
3247
3248
3249bool JSFunction::has_instance_prototype() {
3250 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3251}
3252
3253
3254bool JSFunction::has_prototype() {
3255 return map()->has_non_instance_prototype() || has_instance_prototype();
3256}
3257
3258
3259Object* JSFunction::instance_prototype() {
3260 ASSERT(has_instance_prototype());
3261 if (has_initial_map()) return initial_map()->prototype();
3262 // When there is no initial map and the prototype is a JSObject, the
3263 // initial map field is used for the prototype field.
3264 return prototype_or_initial_map();
3265}
3266
3267
3268Object* JSFunction::prototype() {
3269 ASSERT(has_prototype());
3270 // If the function's prototype property has been set to a non-JSObject
3271 // value, that value is stored in the constructor field of the map.
3272 if (map()->has_non_instance_prototype()) return map()->constructor();
3273 return instance_prototype();
3274}
3275
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003276bool JSFunction::should_have_prototype() {
3277 return map()->function_with_prototype();
3278}
3279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280
3281bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003282 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283}
3284
3285
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003286int JSFunction::NumberOfLiterals() {
3287 return literals()->length();
3288}
3289
3290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003291Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003292 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003293 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003294}
3295
3296
3297void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3298 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003299 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003300 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3301 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3302}
3303
3304
3305Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003306 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003307 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3308}
3309
3310
3311void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3312 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003313 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003314 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3315 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316}
3317
3318
3319Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003320 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003321}
3322
3323
3324void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003325 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003326}
3327
3328
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329ACCESSORS(JSValue, value, Object, kValueOffset)
3330
3331
3332JSValue* JSValue::cast(Object* obj) {
3333 ASSERT(obj->IsJSValue());
3334 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3335 return reinterpret_cast<JSValue*>(obj);
3336}
3337
3338
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003339ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3340ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3341ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3342ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3343ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3344SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3345SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3346
3347
3348JSMessageObject* JSMessageObject::cast(Object* obj) {
3349 ASSERT(obj->IsJSMessageObject());
3350 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3351 return reinterpret_cast<JSMessageObject*>(obj);
3352}
3353
3354
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003355INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003356ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003357ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003358
3359
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360byte* Code::instruction_start() {
3361 return FIELD_ADDR(this, kHeaderSize);
3362}
3363
3364
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003365byte* Code::instruction_end() {
3366 return instruction_start() + instruction_size();
3367}
3368
3369
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003371 return RoundUp(instruction_size(), kObjectAlignment);
3372}
3373
3374
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003375FixedArray* Code::unchecked_deoptimization_data() {
3376 return reinterpret_cast<FixedArray*>(
3377 READ_FIELD(this, kDeoptimizationDataOffset));
3378}
3379
3380
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003381ByteArray* Code::unchecked_relocation_info() {
3382 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383}
3384
3385
3386byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003387 return unchecked_relocation_info()->GetDataStartAddress();
3388}
3389
3390
3391int Code::relocation_size() {
3392 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003393}
3394
3395
3396byte* Code::entry() {
3397 return instruction_start();
3398}
3399
3400
3401bool Code::contains(byte* pc) {
3402 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003403 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003404}
3405
3406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003407ACCESSORS(JSArray, length, Object, kLengthOffset)
3408
3409
ager@chromium.org236ad962008-09-25 09:45:57 +00003410ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003411
3412
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003413JSRegExp::Type JSRegExp::TypeTag() {
3414 Object* data = this->data();
3415 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3416 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3417 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003418}
3419
3420
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003421int JSRegExp::CaptureCount() {
3422 switch (TypeTag()) {
3423 case ATOM:
3424 return 0;
3425 case IRREGEXP:
3426 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3427 default:
3428 UNREACHABLE();
3429 return -1;
3430 }
3431}
3432
3433
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003434JSRegExp::Flags JSRegExp::GetFlags() {
3435 ASSERT(this->data()->IsFixedArray());
3436 Object* data = this->data();
3437 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3438 return Flags(smi->value());
3439}
3440
3441
3442String* JSRegExp::Pattern() {
3443 ASSERT(this->data()->IsFixedArray());
3444 Object* data = this->data();
3445 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3446 return pattern;
3447}
3448
3449
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003450Object* JSRegExp::DataAt(int index) {
3451 ASSERT(TypeTag() != NOT_COMPILED);
3452 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003453}
3454
3455
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003456void JSRegExp::SetDataAt(int index, Object* value) {
3457 ASSERT(TypeTag() != NOT_COMPILED);
3458 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3459 FixedArray::cast(data())->set(index, value);
3460}
3461
3462
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003463JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003464 if (map()->has_fast_elements()) {
3465 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3466 elements()->map() == Heap::fixed_cow_array_map());
3467 return FAST_ELEMENTS;
3468 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003469 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003470 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003471 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3472 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003473 ASSERT(array->IsDictionary());
3474 return DICTIONARY_ELEMENTS;
3475 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003476 if (array->IsExternalArray()) {
3477 switch (array->map()->instance_type()) {
3478 case EXTERNAL_BYTE_ARRAY_TYPE:
3479 return EXTERNAL_BYTE_ELEMENTS;
3480 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3481 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3482 case EXTERNAL_SHORT_ARRAY_TYPE:
3483 return EXTERNAL_SHORT_ELEMENTS;
3484 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3485 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3486 case EXTERNAL_INT_ARRAY_TYPE:
3487 return EXTERNAL_INT_ELEMENTS;
3488 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3489 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003490 case EXTERNAL_PIXEL_ARRAY_TYPE:
3491 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003492 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003493 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003494 }
3495 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003496 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3497 return EXTERNAL_FLOAT_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003498}
3499
3500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003502 return GetElementsKind() == FAST_ELEMENTS;
3503}
3504
3505
3506bool JSObject::HasDictionaryElements() {
3507 return GetElementsKind() == DICTIONARY_ELEMENTS;
3508}
3509
3510
ager@chromium.org3811b432009-10-28 14:53:37 +00003511bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003512 HeapObject* array = elements();
3513 ASSERT(array != NULL);
3514 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003515}
3516
3517
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003518#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3519bool JSObject::HasExternal##name##Elements() { \
3520 HeapObject* array = elements(); \
3521 ASSERT(array != NULL); \
3522 if (!array->IsHeapObject()) \
3523 return false; \
3524 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003525}
3526
3527
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003528EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3529EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3530EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3531EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3532 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3533EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3534EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3535 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3536EXTERNAL_ELEMENTS_CHECK(Float,
3537 EXTERNAL_FLOAT_ARRAY_TYPE)
3538EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003539
3540
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003541bool JSObject::HasNamedInterceptor() {
3542 return map()->has_named_interceptor();
3543}
3544
3545
3546bool JSObject::HasIndexedInterceptor() {
3547 return map()->has_indexed_interceptor();
3548}
3549
3550
ager@chromium.org5c838252010-02-19 08:53:10 +00003551bool JSObject::AllowsSetElementsLength() {
3552 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003553 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003554 return result;
3555}
3556
3557
lrn@chromium.org303ada72010-10-27 09:33:13 +00003558MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003559 ASSERT(HasFastElements());
3560 FixedArray* elems = FixedArray::cast(elements());
3561 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003562 Object* writable_elems;
3563 { MaybeObject* maybe_writable_elems =
3564 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3565 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3566 return maybe_writable_elems;
3567 }
3568 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003569 set_elements(FixedArray::cast(writable_elems));
3570 Counters::cow_arrays_converted.Increment();
3571 return writable_elems;
3572}
3573
3574
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003575StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003576 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003577 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578}
3579
3580
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003581NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003582 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003583 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003584}
3585
3586
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003587bool String::IsHashFieldComputed(uint32_t field) {
3588 return (field & kHashNotComputedMask) == 0;
3589}
3590
3591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003592bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003593 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003594}
3595
3596
3597uint32_t String::Hash() {
3598 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003599 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003600 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003601 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003602 return ComputeAndSetHash();
3603}
3604
3605
ager@chromium.org7c537e22008-10-16 08:43:32 +00003606StringHasher::StringHasher(int length)
3607 : length_(length),
3608 raw_running_hash_(0),
3609 array_index_(0),
3610 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3611 is_first_char_(true),
3612 is_valid_(true) { }
3613
3614
3615bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003616 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003617}
3618
3619
3620void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003621 // Use the Jenkins one-at-a-time hash function to update the hash
3622 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003623 raw_running_hash_ += c;
3624 raw_running_hash_ += (raw_running_hash_ << 10);
3625 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003626 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003627 if (is_array_index_) {
3628 if (c < '0' || c > '9') {
3629 is_array_index_ = false;
3630 } else {
3631 int d = c - '0';
3632 if (is_first_char_) {
3633 is_first_char_ = false;
3634 if (c == '0' && length_ > 1) {
3635 is_array_index_ = false;
3636 return;
3637 }
3638 }
3639 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3640 is_array_index_ = false;
3641 } else {
3642 array_index_ = array_index_ * 10 + d;
3643 }
3644 }
3645 }
3646}
3647
3648
3649void StringHasher::AddCharacterNoIndex(uc32 c) {
3650 ASSERT(!is_array_index());
3651 raw_running_hash_ += c;
3652 raw_running_hash_ += (raw_running_hash_ << 10);
3653 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3654}
3655
3656
3657uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003658 // Get the calculated raw hash value and do some more bit ops to distribute
3659 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003660 uint32_t result = raw_running_hash_;
3661 result += (result << 3);
3662 result ^= (result >> 11);
3663 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003664 if (result == 0) {
3665 result = 27;
3666 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003667 return result;
3668}
3669
3670
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003671template <typename schar>
3672uint32_t HashSequentialString(const schar* chars, int length) {
3673 StringHasher hasher(length);
3674 if (!hasher.has_trivial_hash()) {
3675 int i;
3676 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3677 hasher.AddCharacter(chars[i]);
3678 }
3679 for (; i < length; i++) {
3680 hasher.AddCharacterNoIndex(chars[i]);
3681 }
3682 }
3683 return hasher.GetHashField();
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,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003744 DONT_ENUM,
3745 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003746}
3747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003748
3749bool JSObject::HasElement(uint32_t index) {
3750 return HasElementWithReceiver(this, index);
3751}
3752
3753
3754bool AccessorInfo::all_can_read() {
3755 return BooleanBit::get(flag(), kAllCanReadBit);
3756}
3757
3758
3759void AccessorInfo::set_all_can_read(bool value) {
3760 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3761}
3762
3763
3764bool AccessorInfo::all_can_write() {
3765 return BooleanBit::get(flag(), kAllCanWriteBit);
3766}
3767
3768
3769void AccessorInfo::set_all_can_write(bool value) {
3770 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3771}
3772
3773
ager@chromium.org870a0b62008-11-04 11:43:05 +00003774bool AccessorInfo::prohibits_overwriting() {
3775 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3776}
3777
3778
3779void AccessorInfo::set_prohibits_overwriting(bool value) {
3780 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3781}
3782
3783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784PropertyAttributes AccessorInfo::property_attributes() {
3785 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3786}
3787
3788
3789void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3790 ASSERT(AttributesField::is_valid(attributes));
3791 int rest_value = flag()->value() & ~AttributesField::mask();
3792 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3793}
3794
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003795template<typename Shape, typename Key>
3796void Dictionary<Shape, Key>::SetEntry(int entry,
3797 Object* key,
3798 Object* value,
3799 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003800 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003801 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003802 AssertNoAllocation no_gc;
3803 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003804 FixedArray::set(index, key, mode);
3805 FixedArray::set(index+1, value, mode);
3806 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807}
3808
3809
3810void Map::ClearCodeCache() {
3811 // No write barrier is needed since empty_fixed_array is not in new space.
3812 // Please note this function is used during marking:
3813 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003814 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3815 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003816}
3817
3818
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003819void JSArray::EnsureSize(int required_size) {
3820 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003821 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003822 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3823 if (elts->length() < required_size) {
3824 // Doubling in size would be overkill, but leave some slack to avoid
3825 // constantly growing.
3826 Expand(required_size + (required_size >> 3));
3827 // It's a performance benefit to keep a frequently used array in new-space.
3828 } else if (!Heap::new_space()->Contains(elts) &&
3829 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3830 // Expand will allocate a new backing store in new space even if the size
3831 // we asked for isn't larger than what we had before.
3832 Expand(required_size);
3833 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003834}
3835
3836
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003837void JSArray::set_length(Smi* length) {
3838 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3839}
3840
3841
ager@chromium.org7c537e22008-10-16 08:43:32 +00003842void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003843 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003844 set_elements(storage);
3845}
3846
3847
lrn@chromium.org303ada72010-10-27 09:33:13 +00003848MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003849 if (length() == 0) return this;
3850 return Heap::CopyFixedArray(this);
3851}
3852
3853
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003854int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3855 return map->instance_size();
3856}
3857
3858
3859void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3860 v->VisitExternalReference(
3861 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3862}
3863
3864
3865template<typename StaticVisitor>
3866void Proxy::ProxyIterateBody() {
3867 StaticVisitor::VisitExternalReference(
3868 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3869}
3870
3871
3872void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3873 typedef v8::String::ExternalAsciiStringResource Resource;
3874 v->VisitExternalAsciiString(
3875 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3876}
3877
3878
3879template<typename StaticVisitor>
3880void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3881 typedef v8::String::ExternalAsciiStringResource Resource;
3882 StaticVisitor::VisitExternalAsciiString(
3883 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3884}
3885
3886
3887void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3888 typedef v8::String::ExternalStringResource Resource;
3889 v->VisitExternalTwoByteString(
3890 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3891}
3892
3893
3894template<typename StaticVisitor>
3895void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3896 typedef v8::String::ExternalStringResource Resource;
3897 StaticVisitor::VisitExternalTwoByteString(
3898 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3899}
3900
3901#define SLOT_ADDR(obj, offset) \
3902 reinterpret_cast<Object**>((obj)->address() + offset)
3903
3904template<int start_offset, int end_offset, int size>
3905void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3906 HeapObject* obj,
3907 ObjectVisitor* v) {
3908 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3909}
3910
3911
3912template<int start_offset>
3913void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3914 int object_size,
3915 ObjectVisitor* v) {
3916 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3917}
3918
3919#undef SLOT_ADDR
3920
3921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003922#undef CAST_ACCESSOR
3923#undef INT_ACCESSORS
3924#undef SMI_ACCESSORS
3925#undef ACCESSORS
3926#undef FIELD_ADDR
3927#undef READ_FIELD
3928#undef WRITE_FIELD
3929#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003930#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003931#undef READ_MEMADDR_FIELD
3932#undef WRITE_MEMADDR_FIELD
3933#undef READ_DOUBLE_FIELD
3934#undef WRITE_DOUBLE_FIELD
3935#undef READ_INT_FIELD
3936#undef WRITE_INT_FIELD
3937#undef READ_SHORT_FIELD
3938#undef WRITE_SHORT_FIELD
3939#undef READ_BYTE_FIELD
3940#undef WRITE_BYTE_FIELD
3941
3942
3943} } // namespace v8::internal
3944
3945#endif // V8_OBJECTS_INL_H_