blob: 11f9d34882649e28999717cf8390304f6aaf4e4c [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 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() {
60 PropertyDetails d(DONT_ENUM, NORMAL);
61 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
62 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000082 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083 }
84
85
86#define SMI_ACCESSORS(holder, name, offset) \
87 int holder::name() { \
88 Object* value = READ_FIELD(this, offset); \
89 return Smi::cast(value)->value(); \
90 } \
91 void holder::set_##name(int value) { \
92 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
93 }
94
95
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000096#define BOOL_GETTER(holder, field, name, offset) \
97 bool holder::name() { \
98 return BooleanBit::get(field(), offset); \
99 } \
100
101
102#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000103 bool holder::name() { \
104 return BooleanBit::get(field(), offset); \
105 } \
106 void holder::set_##name(bool value) { \
107 set_##field(BooleanBit::set(field(), offset, value)); \
108 }
109
110
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000111bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
112 // There is a constraint on the object; check.
113 if (!this->IsJSObject()) return false;
114 // Fetch the constructor function of the object.
115 Object* cons_obj = JSObject::cast(this)->map()->constructor();
116 if (!cons_obj->IsJSFunction()) return false;
117 JSFunction* fun = JSFunction::cast(cons_obj);
118 // Iterate through the chain of inheriting function templates to
119 // see if the required one occurs.
120 for (Object* type = fun->shared()->function_data();
121 type->IsFunctionTemplateInfo();
122 type = FunctionTemplateInfo::cast(type)->parent_template()) {
123 if (type == expected) return true;
124 }
125 // Didn't find the required type in the inheritance chain.
126 return false;
127}
128
129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130bool Object::IsSmi() {
131 return HAS_SMI_TAG(this);
132}
133
134
135bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000136 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000137}
138
139
140bool Object::IsHeapNumber() {
141 return Object::IsHeapObject()
142 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
143}
144
145
146bool Object::IsString() {
147 return Object::IsHeapObject()
148 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
149}
150
151
ager@chromium.org870a0b62008-11-04 11:43:05 +0000152bool Object::IsSymbol() {
153 if (!this->IsHeapObject()) return false;
154 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000155 // Because the symbol tag is non-zero and no non-string types have the
156 // symbol bit set we can test for symbols with a very simple test
157 // operation.
158 ASSERT(kSymbolTag != 0);
159 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
160 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161}
162
163
164bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000165 if (!this->IsHeapObject()) return false;
166 uint32_t type = HeapObject::cast(this)->map()->instance_type();
167 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
168 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169}
170
171
ager@chromium.org870a0b62008-11-04 11:43:05 +0000172bool Object::IsSeqString() {
173 if (!IsString()) return false;
174 return StringShape(String::cast(this)).IsSequential();
175}
176
177
178bool Object::IsSeqAsciiString() {
179 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000180 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000181 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000182}
183
184
185bool Object::IsSeqTwoByteString() {
186 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000187 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000188 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189}
190
191
192bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000193 if (!IsString()) return false;
194 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000195}
196
197
198bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000199 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000200 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000201 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202}
203
204
205bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000206 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000207 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000208 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209}
210
211
ager@chromium.org870a0b62008-11-04 11:43:05 +0000212StringShape::StringShape(String* str)
213 : type_(str->map()->instance_type()) {
214 set_valid();
215 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216}
217
218
ager@chromium.org870a0b62008-11-04 11:43:05 +0000219StringShape::StringShape(Map* map)
220 : type_(map->instance_type()) {
221 set_valid();
222 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223}
224
225
ager@chromium.org870a0b62008-11-04 11:43:05 +0000226StringShape::StringShape(InstanceType t)
227 : type_(static_cast<uint32_t>(t)) {
228 set_valid();
229 ASSERT((type_ & kIsNotStringMask) == kStringTag);
230}
231
232
233bool StringShape::IsSymbol() {
234 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000235 ASSERT(kSymbolTag != 0);
236 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000237}
238
239
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240bool String::IsAsciiRepresentation() {
241 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000242 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000243}
244
245
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246bool String::IsTwoByteRepresentation() {
247 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000249}
250
251
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000252bool String::HasOnlyAsciiChars() {
253 uint32_t type = map()->instance_type();
254 return (type & kStringEncodingMask) == kAsciiStringTag ||
255 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000256}
257
258
ager@chromium.org870a0b62008-11-04 11:43:05 +0000259bool StringShape::IsCons() {
260 return (type_ & kStringRepresentationMask) == kConsStringTag;
261}
262
263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264bool StringShape::IsExternal() {
265 return (type_ & kStringRepresentationMask) == kExternalStringTag;
266}
267
268
269bool StringShape::IsSequential() {
270 return (type_ & kStringRepresentationMask) == kSeqStringTag;
271}
272
273
274StringRepresentationTag StringShape::representation_tag() {
275 uint32_t tag = (type_ & kStringRepresentationMask);
276 return static_cast<StringRepresentationTag>(tag);
277}
278
279
280uint32_t StringShape::full_representation_tag() {
281 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
282}
283
284
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000285STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
286 Internals::kFullStringRepresentationMask);
287
288
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289bool StringShape::IsSequentialAscii() {
290 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
291}
292
293
294bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000295 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000296}
297
298
299bool StringShape::IsExternalAscii() {
300 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
301}
302
303
304bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000305 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306}
307
308
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000309STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
310 Internals::kExternalTwoByteRepresentationTag);
311
312
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000313uc32 FlatStringReader::Get(int index) {
314 ASSERT(0 <= index && index <= length_);
315 if (is_ascii_) {
316 return static_cast<const byte*>(start_)[index];
317 } else {
318 return static_cast<const uc16*>(start_)[index];
319 }
320}
321
322
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000323bool Object::IsNumber() {
324 return IsSmi() || IsHeapNumber();
325}
326
327
328bool Object::IsByteArray() {
329 return Object::IsHeapObject()
330 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
331}
332
333
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000334bool Object::IsPixelArray() {
335 return Object::IsHeapObject() &&
336 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
337}
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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000399bool Object::IsFailure() {
400 return HAS_FAILURE_TAG(this);
401}
402
403
404bool Object::IsRetryAfterGC() {
405 return HAS_FAILURE_TAG(this)
406 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
407}
408
409
ager@chromium.org7c537e22008-10-16 08:43:32 +0000410bool Object::IsOutOfMemoryFailure() {
411 return HAS_FAILURE_TAG(this)
412 && Failure::cast(this)->IsOutOfMemoryException();
413}
414
415
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000416bool Object::IsException() {
417 return this == Failure::Exception();
418}
419
420
421bool Object::IsJSObject() {
422 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000423 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000424}
425
426
ager@chromium.org32912102009-01-16 10:38:43 +0000427bool Object::IsJSContextExtensionObject() {
428 return IsHeapObject()
429 && (HeapObject::cast(this)->map()->instance_type() ==
430 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
431}
432
433
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434bool Object::IsMap() {
435 return Object::IsHeapObject()
436 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
437}
438
439
440bool Object::IsFixedArray() {
441 return Object::IsHeapObject()
442 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
443}
444
445
446bool Object::IsDescriptorArray() {
447 return IsFixedArray();
448}
449
450
451bool Object::IsContext() {
452 return Object::IsHeapObject()
453 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000454 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000455 HeapObject::cast(this)->map() == Heap::global_context_map());
456}
457
458
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000459bool Object::IsCatchContext() {
460 return Object::IsHeapObject()
461 && HeapObject::cast(this)->map() == Heap::catch_context_map();
462}
463
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465bool Object::IsGlobalContext() {
466 return Object::IsHeapObject()
467 && HeapObject::cast(this)->map() == Heap::global_context_map();
468}
469
470
471bool Object::IsJSFunction() {
472 return Object::IsHeapObject()
473 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
474}
475
476
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000477template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000478 return obj->IsJSFunction();
479}
480
481
482bool Object::IsCode() {
483 return Object::IsHeapObject()
484 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
485}
486
487
488bool Object::IsOddball() {
489 return Object::IsHeapObject()
490 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
491}
492
493
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000494bool Object::IsJSGlobalPropertyCell() {
495 return Object::IsHeapObject()
496 && HeapObject::cast(this)->map()->instance_type()
497 == JS_GLOBAL_PROPERTY_CELL_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsSharedFunctionInfo() {
502 return Object::IsHeapObject() &&
503 (HeapObject::cast(this)->map()->instance_type() ==
504 SHARED_FUNCTION_INFO_TYPE);
505}
506
507
508bool Object::IsJSValue() {
509 return Object::IsHeapObject()
510 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
511}
512
513
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000514bool Object::IsStringWrapper() {
515 return IsJSValue() && JSValue::cast(this)->value()->IsString();
516}
517
518
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519bool Object::IsProxy() {
520 return Object::IsHeapObject()
521 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
522}
523
524
525bool Object::IsBoolean() {
526 return IsTrue() || IsFalse();
527}
528
529
530bool Object::IsJSArray() {
531 return Object::IsHeapObject()
532 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
533}
534
535
ager@chromium.org236ad962008-09-25 09:45:57 +0000536bool Object::IsJSRegExp() {
537 return Object::IsHeapObject()
538 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
539}
540
541
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000542template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000543 return obj->IsJSArray();
544}
545
546
547bool Object::IsHashTable() {
548 return Object::IsHeapObject()
549 && HeapObject::cast(this)->map() == Heap::hash_table_map();
550}
551
552
553bool Object::IsDictionary() {
554 return IsHashTable() && this != Heap::symbol_table();
555}
556
557
558bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000559 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000560}
561
562
ager@chromium.orgac091b72010-05-05 07:34:42 +0000563bool Object::IsJSFunctionResultCache() {
564 if (!IsFixedArray()) return false;
565 FixedArray* self = FixedArray::cast(this);
566 int length = self->length();
567 if (length < JSFunctionResultCache::kEntriesIndex) return false;
568 if ((length - JSFunctionResultCache::kEntriesIndex)
569 % JSFunctionResultCache::kEntrySize != 0) {
570 return false;
571 }
572#ifdef DEBUG
573 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
574#endif
575 return true;
576}
577
578
ricow@chromium.org65fae842010-08-25 15:26:24 +0000579bool Object::IsNormalizedMapCache() {
580 if (!IsFixedArray()) return false;
581 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
582 return false;
583 }
584#ifdef DEBUG
585 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
586#endif
587 return true;
588}
589
590
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000591bool Object::IsCompilationCacheTable() {
592 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000593}
594
595
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000596bool Object::IsCodeCacheHashTable() {
597 return IsHashTable();
598}
599
600
ager@chromium.org236ad962008-09-25 09:45:57 +0000601bool Object::IsMapCache() {
602 return IsHashTable();
603}
604
605
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000606bool Object::IsPrimitive() {
607 return IsOddball() || IsNumber() || IsString();
608}
609
610
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000611bool Object::IsJSGlobalProxy() {
612 bool result = IsHeapObject() &&
613 (HeapObject::cast(this)->map()->instance_type() ==
614 JS_GLOBAL_PROXY_TYPE);
615 ASSERT(!result || IsAccessCheckNeeded());
616 return result;
617}
618
619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000621 if (!IsHeapObject()) return false;
622
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000623 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000624 return type == JS_GLOBAL_OBJECT_TYPE ||
625 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630 return IsHeapObject() &&
631 (HeapObject::cast(this)->map()->instance_type() ==
632 JS_GLOBAL_OBJECT_TYPE);
633}
634
635
636bool Object::IsJSBuiltinsObject() {
637 return IsHeapObject() &&
638 (HeapObject::cast(this)->map()->instance_type() ==
639 JS_BUILTINS_OBJECT_TYPE);
640}
641
642
643bool Object::IsUndetectableObject() {
644 return IsHeapObject()
645 && HeapObject::cast(this)->map()->is_undetectable();
646}
647
648
649bool Object::IsAccessCheckNeeded() {
650 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000651 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000652}
653
654
655bool Object::IsStruct() {
656 if (!IsHeapObject()) return false;
657 switch (HeapObject::cast(this)->map()->instance_type()) {
658#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
659 STRUCT_LIST(MAKE_STRUCT_CASE)
660#undef MAKE_STRUCT_CASE
661 default: return false;
662 }
663}
664
665
666#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
667 bool Object::Is##Name() { \
668 return Object::IsHeapObject() \
669 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
670 }
671 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
672#undef MAKE_STRUCT_PREDICATE
673
674
675bool Object::IsUndefined() {
676 return this == Heap::undefined_value();
677}
678
679
680bool Object::IsTheHole() {
681 return this == Heap::the_hole_value();
682}
683
684
685bool Object::IsNull() {
686 return this == Heap::null_value();
687}
688
689
690bool Object::IsTrue() {
691 return this == Heap::true_value();
692}
693
694
695bool Object::IsFalse() {
696 return this == Heap::false_value();
697}
698
699
700double Object::Number() {
701 ASSERT(IsNumber());
702 return IsSmi()
703 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
704 : reinterpret_cast<HeapNumber*>(this)->value();
705}
706
707
708
709Object* Object::ToSmi() {
710 if (IsSmi()) return this;
711 if (IsHeapNumber()) {
712 double value = HeapNumber::cast(this)->value();
713 int int_value = FastD2I(value);
714 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
715 return Smi::FromInt(int_value);
716 }
717 }
718 return Failure::Exception();
719}
720
721
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000722bool Object::HasSpecificClassOf(String* name) {
723 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
724}
725
726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727Object* Object::GetElement(uint32_t index) {
728 return GetElementWithReceiver(this, index);
729}
730
731
732Object* Object::GetProperty(String* key) {
733 PropertyAttributes attributes;
734 return GetPropertyWithReceiver(this, key, &attributes);
735}
736
737
738Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
739 return GetPropertyWithReceiver(this, key, attributes);
740}
741
742
743#define FIELD_ADDR(p, offset) \
744 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
745
746#define READ_FIELD(p, offset) \
747 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
748
749#define WRITE_FIELD(p, offset, value) \
750 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
751
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000752
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753#define WRITE_BARRIER(object, offset) \
754 Heap::RecordWrite(object->address(), offset);
755
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000756// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000757// write due to the assert validating the written value.
758#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
759 if (mode == UPDATE_WRITE_BARRIER) { \
760 Heap::RecordWrite(object->address(), offset); \
761 } else { \
762 ASSERT(mode == SKIP_WRITE_BARRIER); \
763 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000764 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000765 Page::FromAddress(object->address())-> \
766 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000767 }
768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000769#define READ_DOUBLE_FIELD(p, offset) \
770 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
771
772#define WRITE_DOUBLE_FIELD(p, offset, value) \
773 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
774
775#define READ_INT_FIELD(p, offset) \
776 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
777
778#define WRITE_INT_FIELD(p, offset, value) \
779 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
780
ager@chromium.org3e875802009-06-29 08:26:34 +0000781#define READ_INTPTR_FIELD(p, offset) \
782 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
783
784#define WRITE_INTPTR_FIELD(p, offset, value) \
785 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
786
ager@chromium.org7c537e22008-10-16 08:43:32 +0000787#define READ_UINT32_FIELD(p, offset) \
788 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
789
790#define WRITE_UINT32_FIELD(p, offset, value) \
791 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
792
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000793#define READ_SHORT_FIELD(p, offset) \
794 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
795
796#define WRITE_SHORT_FIELD(p, offset, value) \
797 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
798
799#define READ_BYTE_FIELD(p, offset) \
800 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
801
802#define WRITE_BYTE_FIELD(p, offset, value) \
803 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
804
805
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000806Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
807 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808}
809
810
811int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000812 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000813}
814
815
816Smi* Smi::FromInt(int value) {
817 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000818 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000819 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000820 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000821 return reinterpret_cast<Smi*>(tagged_value);
822}
823
824
825Smi* Smi::FromIntptr(intptr_t value) {
826 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000827 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
828 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000829}
830
831
832Failure::Type Failure::type() const {
833 return static_cast<Type>(value() & kFailureTypeTagMask);
834}
835
836
837bool Failure::IsInternalError() const {
838 return type() == INTERNAL_ERROR;
839}
840
841
842bool Failure::IsOutOfMemoryException() const {
843 return type() == OUT_OF_MEMORY_EXCEPTION;
844}
845
846
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000847AllocationSpace Failure::allocation_space() const {
848 ASSERT_EQ(RETRY_AFTER_GC, type());
849 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
850 & kSpaceTagMask);
851}
852
853
854Failure* Failure::InternalError() {
855 return Construct(INTERNAL_ERROR);
856}
857
858
859Failure* Failure::Exception() {
860 return Construct(EXCEPTION);
861}
862
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864Failure* Failure::OutOfMemoryException() {
865 return Construct(OUT_OF_MEMORY_EXCEPTION);
866}
867
868
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000869intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000870 return static_cast<intptr_t>(
871 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000872}
873
874
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000875Failure* Failure::RetryAfterGC() {
876 return RetryAfterGC(NEW_SPACE);
877}
878
879
880Failure* Failure::RetryAfterGC(AllocationSpace space) {
881 ASSERT((space & ~kSpaceTagMask) == 0);
882 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883}
884
885
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000886Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000887 uintptr_t info =
888 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000889 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000890 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891}
892
893
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000894bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000895#ifdef DEBUG
896 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
897#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898
899#ifdef V8_TARGET_ARCH_X64
900 // To be representable as a long smi, the value must be a 32-bit integer.
901 bool result = (value == static_cast<int32_t>(value));
902#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903 // To be representable as an tagged small integer, the two
904 // most-significant bits of 'value' must be either 00 or 11 due to
905 // sign-extension. To check this we add 01 to the two
906 // most-significant bits, and check if the most-significant bit is 0
907 //
908 // CAUTION: The original code below:
909 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
910 // may lead to incorrect results according to the C language spec, and
911 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
912 // compiler may produce undefined results in case of signed integer
913 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000914 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000915#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000916 ASSERT(result == in_range);
917 return result;
918}
919
920
kasper.lund7276f142008-07-30 08:49:36 +0000921MapWord MapWord::FromMap(Map* map) {
922 return MapWord(reinterpret_cast<uintptr_t>(map));
923}
924
925
926Map* MapWord::ToMap() {
927 return reinterpret_cast<Map*>(value_);
928}
929
930
931bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000932 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000933}
934
935
936MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000937 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
938 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000939}
940
941
942HeapObject* MapWord::ToForwardingAddress() {
943 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000944 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000945}
946
947
948bool MapWord::IsMarked() {
949 return (value_ & kMarkingMask) == 0;
950}
951
952
953void MapWord::SetMark() {
954 value_ &= ~kMarkingMask;
955}
956
957
958void MapWord::ClearMark() {
959 value_ |= kMarkingMask;
960}
961
962
963bool MapWord::IsOverflowed() {
964 return (value_ & kOverflowMask) != 0;
965}
966
967
968void MapWord::SetOverflow() {
969 value_ |= kOverflowMask;
970}
971
972
973void MapWord::ClearOverflow() {
974 value_ &= ~kOverflowMask;
975}
976
977
978MapWord MapWord::EncodeAddress(Address map_address, int offset) {
979 // Offset is the distance in live bytes from the first live object in the
980 // same page. The offset between two objects in the same page should not
981 // exceed the object area size of a page.
982 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
983
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000984 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000985 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
986
987 Page* map_page = Page::FromAddress(map_address);
988 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
989
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000990 uintptr_t map_page_offset =
991 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000992
993 uintptr_t encoding =
994 (compact_offset << kForwardingOffsetShift) |
995 (map_page_offset << kMapPageOffsetShift) |
996 (map_page->mc_page_index << kMapPageIndexShift);
997 return MapWord(encoding);
998}
999
1000
1001Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001002 int map_page_index =
1003 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001004 ASSERT_MAP_PAGE_INDEX(map_page_index);
1005
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001006 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001007 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1008 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001009
1010 return (map_space->PageAddress(map_page_index) + map_page_offset);
1011}
1012
1013
1014int MapWord::DecodeOffset() {
1015 // The offset field is represented in the kForwardingOffsetBits
1016 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001017 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1018 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1019 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001020}
1021
1022
1023MapWord MapWord::FromEncodedAddress(Address address) {
1024 return MapWord(reinterpret_cast<uintptr_t>(address));
1025}
1026
1027
1028Address MapWord::ToEncodedAddress() {
1029 return reinterpret_cast<Address>(value_);
1030}
1031
1032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033#ifdef DEBUG
1034void HeapObject::VerifyObjectField(int offset) {
1035 VerifyPointer(READ_FIELD(this, offset));
1036}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001037
1038void HeapObject::VerifySmiField(int offset) {
1039 ASSERT(READ_FIELD(this, offset)->IsSmi());
1040}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041#endif
1042
1043
1044Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001045 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001046}
1047
1048
1049void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001050 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001051}
1052
1053
kasper.lund7276f142008-07-30 08:49:36 +00001054MapWord HeapObject::map_word() {
1055 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1056}
1057
1058
1059void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001060 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001061 // here.
1062 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1063}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001064
1065
1066HeapObject* HeapObject::FromAddress(Address address) {
1067 ASSERT_TAG_ALIGNED(address);
1068 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1069}
1070
1071
1072Address HeapObject::address() {
1073 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1074}
1075
1076
1077int HeapObject::Size() {
1078 return SizeFromMap(map());
1079}
1080
1081
1082void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1083 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1084 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1085}
1086
1087
1088void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1089 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1090}
1091
1092
kasper.lund7276f142008-07-30 08:49:36 +00001093bool HeapObject::IsMarked() {
1094 return map_word().IsMarked();
1095}
1096
1097
1098void HeapObject::SetMark() {
1099 ASSERT(!IsMarked());
1100 MapWord first_word = map_word();
1101 first_word.SetMark();
1102 set_map_word(first_word);
1103}
1104
1105
1106void HeapObject::ClearMark() {
1107 ASSERT(IsMarked());
1108 MapWord first_word = map_word();
1109 first_word.ClearMark();
1110 set_map_word(first_word);
1111}
1112
1113
1114bool HeapObject::IsOverflowed() {
1115 return map_word().IsOverflowed();
1116}
1117
1118
1119void HeapObject::SetOverflow() {
1120 MapWord first_word = map_word();
1121 first_word.SetOverflow();
1122 set_map_word(first_word);
1123}
1124
1125
1126void HeapObject::ClearOverflow() {
1127 ASSERT(IsOverflowed());
1128 MapWord first_word = map_word();
1129 first_word.ClearOverflow();
1130 set_map_word(first_word);
1131}
1132
1133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001134double HeapNumber::value() {
1135 return READ_DOUBLE_FIELD(this, kValueOffset);
1136}
1137
1138
1139void HeapNumber::set_value(double value) {
1140 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1141}
1142
1143
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001144int HeapNumber::get_exponent() {
1145 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1146 kExponentShift) - kExponentBias;
1147}
1148
1149
1150int HeapNumber::get_sign() {
1151 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1152}
1153
1154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001155ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001156
1157
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001158HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001159 Object* array = READ_FIELD(this, kElementsOffset);
1160 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001161 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1162 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001163 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001164}
1165
1166
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001167void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001168 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001169 (value->map() == Heap::fixed_array_map() ||
1170 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001171 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001172 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1173 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001174 WRITE_FIELD(this, kElementsOffset, value);
1175 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1176}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001177
1178
1179void JSObject::initialize_properties() {
1180 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1181 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1182}
1183
1184
1185void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001186 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1188 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1189}
1190
1191
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001192Object* JSObject::ResetElements() {
1193 Object* obj = map()->GetFastElementsMap();
1194 if (obj->IsFailure()) return obj;
1195 set_map(Map::cast(obj));
1196 initialize_elements();
1197 return this;
1198}
1199
1200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001201ACCESSORS(Oddball, to_string, String, kToStringOffset)
1202ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1203
1204
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001205Object* JSGlobalPropertyCell::value() {
1206 return READ_FIELD(this, kValueOffset);
1207}
1208
1209
1210void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1211 // The write barrier is not used for global property cells.
1212 ASSERT(!val->IsJSGlobalPropertyCell());
1213 WRITE_FIELD(this, kValueOffset, val);
1214}
1215
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001218 InstanceType type = map()->instance_type();
1219 // Check for the most common kind of JavaScript object before
1220 // falling into the generic switch. This speeds up the internal
1221 // field operations considerably on average.
1222 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1223 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001224 case JS_GLOBAL_PROXY_TYPE:
1225 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001226 case JS_GLOBAL_OBJECT_TYPE:
1227 return JSGlobalObject::kSize;
1228 case JS_BUILTINS_OBJECT_TYPE:
1229 return JSBuiltinsObject::kSize;
1230 case JS_FUNCTION_TYPE:
1231 return JSFunction::kSize;
1232 case JS_VALUE_TYPE:
1233 return JSValue::kSize;
1234 case JS_ARRAY_TYPE:
1235 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001236 case JS_REGEXP_TYPE:
1237 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001238 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239 return JSObject::kHeaderSize;
1240 default:
1241 UNREACHABLE();
1242 return 0;
1243 }
1244}
1245
1246
1247int JSObject::GetInternalFieldCount() {
1248 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001249 // Make sure to adjust for the number of in-object properties. These
1250 // properties do contribute to the size, but are not internal fields.
1251 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1252 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001253}
1254
1255
1256Object* JSObject::GetInternalField(int index) {
1257 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001258 // Internal objects do follow immediately after the header, whereas in-object
1259 // properties are at the end of the object. Therefore there is no need
1260 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1262}
1263
1264
1265void JSObject::SetInternalField(int index, Object* value) {
1266 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001267 // Internal objects do follow immediately after the header, whereas in-object
1268 // properties are at the end of the object. Therefore there is no need
1269 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001270 int offset = GetHeaderSize() + (kPointerSize * index);
1271 WRITE_FIELD(this, offset, value);
1272 WRITE_BARRIER(this, offset);
1273}
1274
1275
ager@chromium.org7c537e22008-10-16 08:43:32 +00001276// Access fast-case object properties at index. The use of these routines
1277// is needed to correctly distinguish between properties stored in-object and
1278// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001279Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001280 // Adjust for the number of properties stored in the object.
1281 index -= map()->inobject_properties();
1282 if (index < 0) {
1283 int offset = map()->instance_size() + (index * kPointerSize);
1284 return READ_FIELD(this, offset);
1285 } else {
1286 ASSERT(index < properties()->length());
1287 return properties()->get(index);
1288 }
1289}
1290
1291
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001292Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001293 // Adjust for the number of properties stored in the object.
1294 index -= map()->inobject_properties();
1295 if (index < 0) {
1296 int offset = map()->instance_size() + (index * kPointerSize);
1297 WRITE_FIELD(this, offset, value);
1298 WRITE_BARRIER(this, offset);
1299 } else {
1300 ASSERT(index < properties()->length());
1301 properties()->set(index, value);
1302 }
1303 return value;
1304}
1305
1306
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001307Object* JSObject::InObjectPropertyAt(int index) {
1308 // Adjust for the number of properties stored in the object.
1309 index -= map()->inobject_properties();
1310 ASSERT(index < 0);
1311 int offset = map()->instance_size() + (index * kPointerSize);
1312 return READ_FIELD(this, offset);
1313}
1314
1315
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001316Object* JSObject::InObjectPropertyAtPut(int index,
1317 Object* value,
1318 WriteBarrierMode mode) {
1319 // Adjust for the number of properties stored in the object.
1320 index -= map()->inobject_properties();
1321 ASSERT(index < 0);
1322 int offset = map()->instance_size() + (index * kPointerSize);
1323 WRITE_FIELD(this, offset, value);
1324 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1325 return value;
1326}
1327
1328
1329
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001330void JSObject::InitializeBody(int object_size, Object* value) {
1331 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001332 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001333 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334 }
1335}
1336
1337
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001338bool JSObject::HasFastProperties() {
1339 return !properties()->IsDictionary();
1340}
1341
1342
1343int JSObject::MaxFastProperties() {
1344 // Allow extra fast properties if the object has more than
1345 // kMaxFastProperties in-object properties. When this is the case,
1346 // it is very unlikely that the object is being used as a dictionary
1347 // and there is a good chance that allowing more map transitions
1348 // will be worth it.
1349 return Max(map()->inobject_properties(), kMaxFastProperties);
1350}
1351
1352
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001353void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001354 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001355 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001356 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357 }
1358}
1359
1360
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001361bool Object::ToArrayIndex(uint32_t* index) {
1362 if (IsSmi()) {
1363 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001364 if (value < 0) return false;
1365 *index = value;
1366 return true;
1367 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001368 if (IsHeapNumber()) {
1369 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370 uint32_t uint_value = static_cast<uint32_t>(value);
1371 if (value == static_cast<double>(uint_value)) {
1372 *index = uint_value;
1373 return true;
1374 }
1375 }
1376 return false;
1377}
1378
1379
1380bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1381 if (!this->IsJSValue()) return false;
1382
1383 JSValue* js_value = JSValue::cast(this);
1384 if (!js_value->value()->IsString()) return false;
1385
1386 String* str = String::cast(js_value->value());
1387 if (index >= (uint32_t)str->length()) return false;
1388
1389 return true;
1390}
1391
1392
1393Object* FixedArray::get(int index) {
1394 ASSERT(index >= 0 && index < this->length());
1395 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1396}
1397
1398
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001399void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001400 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001401 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1402 int offset = kHeaderSize + index * kPointerSize;
1403 WRITE_FIELD(this, offset, value);
1404}
1405
1406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001408 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409 ASSERT(index >= 0 && index < this->length());
1410 int offset = kHeaderSize + index * kPointerSize;
1411 WRITE_FIELD(this, offset, value);
1412 WRITE_BARRIER(this, offset);
1413}
1414
1415
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001416WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1418 return UPDATE_WRITE_BARRIER;
1419}
1420
1421
1422void FixedArray::set(int index,
1423 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001424 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001425 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426 ASSERT(index >= 0 && index < this->length());
1427 int offset = kHeaderSize + index * kPointerSize;
1428 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001429 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430}
1431
1432
1433void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001434 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001436 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001437 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1438}
1439
1440
1441void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001442 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443 ASSERT(index >= 0 && index < this->length());
1444 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1445 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1446 Heap::undefined_value());
1447}
1448
1449
ager@chromium.org236ad962008-09-25 09:45:57 +00001450void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001451 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001452 ASSERT(index >= 0 && index < this->length());
1453 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1454 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1455}
1456
1457
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001459 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460 ASSERT(index >= 0 && index < this->length());
1461 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1462 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1463}
1464
1465
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001466void FixedArray::set_unchecked(int index, Smi* value) {
1467 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1468 int offset = kHeaderSize + index * kPointerSize;
1469 WRITE_FIELD(this, offset, value);
1470}
1471
1472
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001473void FixedArray::set_unchecked(int index,
1474 Object* value,
1475 WriteBarrierMode mode) {
1476 int offset = kHeaderSize + index * kPointerSize;
1477 WRITE_FIELD(this, offset, value);
1478 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1479}
1480
1481
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001482void FixedArray::set_null_unchecked(int index) {
1483 ASSERT(index >= 0 && index < this->length());
1484 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1485 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1486}
1487
1488
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001489Object** FixedArray::data_start() {
1490 return HeapObject::RawField(this, kHeaderSize);
1491}
1492
1493
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001494bool DescriptorArray::IsEmpty() {
1495 ASSERT(this == Heap::empty_descriptor_array() ||
1496 this->length() > 2);
1497 return this == Heap::empty_descriptor_array();
1498}
1499
1500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001501void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1502 Object* tmp = array->get(first);
1503 fast_set(array, first, array->get(second));
1504 fast_set(array, second, tmp);
1505}
1506
1507
1508int DescriptorArray::Search(String* name) {
1509 SLOW_ASSERT(IsSortedNoDuplicates());
1510
1511 // Check for empty descriptor array.
1512 int nof = number_of_descriptors();
1513 if (nof == 0) return kNotFound;
1514
1515 // Fast case: do linear search for small arrays.
1516 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001517 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001518 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001519 }
1520
1521 // Slow case: perform binary search.
1522 return BinarySearch(name, 0, nof - 1);
1523}
1524
1525
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001526int DescriptorArray::SearchWithCache(String* name) {
1527 int number = DescriptorLookupCache::Lookup(this, name);
1528 if (number == DescriptorLookupCache::kAbsent) {
1529 number = Search(name);
1530 DescriptorLookupCache::Update(this, name, number);
1531 }
1532 return number;
1533}
1534
1535
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001536String* DescriptorArray::GetKey(int descriptor_number) {
1537 ASSERT(descriptor_number < number_of_descriptors());
1538 return String::cast(get(ToKeyIndex(descriptor_number)));
1539}
1540
1541
1542Object* DescriptorArray::GetValue(int descriptor_number) {
1543 ASSERT(descriptor_number < number_of_descriptors());
1544 return GetContentArray()->get(ToValueIndex(descriptor_number));
1545}
1546
1547
1548Smi* DescriptorArray::GetDetails(int descriptor_number) {
1549 ASSERT(descriptor_number < number_of_descriptors());
1550 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1551}
1552
1553
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001554PropertyType DescriptorArray::GetType(int descriptor_number) {
1555 ASSERT(descriptor_number < number_of_descriptors());
1556 return PropertyDetails(GetDetails(descriptor_number)).type();
1557}
1558
1559
1560int DescriptorArray::GetFieldIndex(int descriptor_number) {
1561 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1562}
1563
1564
1565JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1566 return JSFunction::cast(GetValue(descriptor_number));
1567}
1568
1569
1570Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1571 ASSERT(GetType(descriptor_number) == CALLBACKS);
1572 return GetValue(descriptor_number);
1573}
1574
1575
1576AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1577 ASSERT(GetType(descriptor_number) == CALLBACKS);
1578 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1579 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1580}
1581
1582
1583bool DescriptorArray::IsProperty(int descriptor_number) {
1584 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1585}
1586
1587
1588bool DescriptorArray::IsTransition(int descriptor_number) {
1589 PropertyType t = GetType(descriptor_number);
1590 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1591}
1592
1593
1594bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1595 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1596}
1597
1598
1599bool DescriptorArray::IsDontEnum(int descriptor_number) {
1600 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1601}
1602
1603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1605 desc->Init(GetKey(descriptor_number),
1606 GetValue(descriptor_number),
1607 GetDetails(descriptor_number));
1608}
1609
1610
1611void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1612 // Range check.
1613 ASSERT(descriptor_number < number_of_descriptors());
1614
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001615 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1617 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1618
1619 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1620 FixedArray* content_array = GetContentArray();
1621 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1622 fast_set(content_array, ToDetailsIndex(descriptor_number),
1623 desc->GetDetails().AsSmi());
1624}
1625
1626
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001627void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1628 Descriptor desc;
1629 src->Get(src_index, &desc);
1630 Set(index, &desc);
1631}
1632
1633
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001634void DescriptorArray::Swap(int first, int second) {
1635 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1636 FixedArray* content_array = GetContentArray();
1637 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1638 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1639}
1640
1641
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001642bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001643 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644 if (!max_index_object->IsSmi()) return false;
1645 return 0 !=
1646 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1647}
1648
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001649uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001650 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001651 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001652 if (!max_index_object->IsSmi()) return 0;
1653 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1654 return value >> kRequiresSlowElementsTagSize;
1655}
1656
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001657void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001658 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001659}
1660
1661
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001662// ------------------------------------
1663// Cast operations
1664
1665
1666CAST_ACCESSOR(FixedArray)
1667CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001669CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001670CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001671CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001672CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001673CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001674CAST_ACCESSOR(String)
1675CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001676CAST_ACCESSOR(SeqAsciiString)
1677CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001678CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001679CAST_ACCESSOR(ExternalString)
1680CAST_ACCESSOR(ExternalAsciiString)
1681CAST_ACCESSOR(ExternalTwoByteString)
1682CAST_ACCESSOR(JSObject)
1683CAST_ACCESSOR(Smi)
1684CAST_ACCESSOR(Failure)
1685CAST_ACCESSOR(HeapObject)
1686CAST_ACCESSOR(HeapNumber)
1687CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001688CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001689CAST_ACCESSOR(SharedFunctionInfo)
1690CAST_ACCESSOR(Map)
1691CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001692CAST_ACCESSOR(GlobalObject)
1693CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694CAST_ACCESSOR(JSGlobalObject)
1695CAST_ACCESSOR(JSBuiltinsObject)
1696CAST_ACCESSOR(Code)
1697CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001698CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699CAST_ACCESSOR(Proxy)
1700CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001701CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001702CAST_ACCESSOR(ExternalArray)
1703CAST_ACCESSOR(ExternalByteArray)
1704CAST_ACCESSOR(ExternalUnsignedByteArray)
1705CAST_ACCESSOR(ExternalShortArray)
1706CAST_ACCESSOR(ExternalUnsignedShortArray)
1707CAST_ACCESSOR(ExternalIntArray)
1708CAST_ACCESSOR(ExternalUnsignedIntArray)
1709CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710CAST_ACCESSOR(Struct)
1711
1712
1713#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1714 STRUCT_LIST(MAKE_STRUCT_CAST)
1715#undef MAKE_STRUCT_CAST
1716
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001717
1718template <typename Shape, typename Key>
1719HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720 ASSERT(obj->IsHashTable());
1721 return reinterpret_cast<HashTable*>(obj);
1722}
1723
1724
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001725SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1726SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1727
1728INT_ACCESSORS(PixelArray, length, kLengthOffset)
1729INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730
1731
ager@chromium.orgac091b72010-05-05 07:34:42 +00001732SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001733
1734
1735uint32_t String::hash_field() {
1736 return READ_UINT32_FIELD(this, kHashFieldOffset);
1737}
1738
1739
1740void String::set_hash_field(uint32_t value) {
1741 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001742#if V8_HOST_ARCH_64_BIT
1743 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1744#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001745}
1746
1747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748bool String::Equals(String* other) {
1749 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001750 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1751 return false;
1752 }
1753 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754}
1755
1756
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001757Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001758 if (!StringShape(this).IsCons()) return this;
1759 ConsString* cons = ConsString::cast(this);
1760 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001761 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001762}
1763
1764
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001765String* String::TryFlattenGetString(PretenureFlag pretenure) {
1766 Object* flat = TryFlatten(pretenure);
1767 return flat->IsFailure() ? this : String::cast(flat);
1768}
1769
1770
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001771uint16_t String::Get(int index) {
1772 ASSERT(index >= 0 && index < length());
1773 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001774 case kSeqStringTag | kAsciiStringTag:
1775 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1776 case kSeqStringTag | kTwoByteStringTag:
1777 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1778 case kConsStringTag | kAsciiStringTag:
1779 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001781 case kExternalStringTag | kAsciiStringTag:
1782 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1783 case kExternalStringTag | kTwoByteStringTag:
1784 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001785 default:
1786 break;
1787 }
1788
1789 UNREACHABLE();
1790 return 0;
1791}
1792
1793
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001794void String::Set(int index, uint16_t value) {
1795 ASSERT(index >= 0 && index < length());
1796 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797
ager@chromium.org5ec48922009-05-05 07:25:34 +00001798 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001799 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1800 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801}
1802
1803
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001804bool String::IsFlat() {
1805 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001806 case kConsStringTag: {
1807 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001808 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001809 return second->length() == 0;
1810 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001811 default:
1812 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813 }
1814}
1815
1816
ager@chromium.org7c537e22008-10-16 08:43:32 +00001817uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818 ASSERT(index >= 0 && index < length());
1819 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1820}
1821
1822
ager@chromium.org7c537e22008-10-16 08:43:32 +00001823void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1825 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1826 static_cast<byte>(value));
1827}
1828
1829
ager@chromium.org7c537e22008-10-16 08:43:32 +00001830Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 return FIELD_ADDR(this, kHeaderSize);
1832}
1833
1834
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001835char* SeqAsciiString::GetChars() {
1836 return reinterpret_cast<char*>(GetCharsAddress());
1837}
1838
1839
ager@chromium.org7c537e22008-10-16 08:43:32 +00001840Address SeqTwoByteString::GetCharsAddress() {
1841 return FIELD_ADDR(this, kHeaderSize);
1842}
1843
1844
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001845uc16* SeqTwoByteString::GetChars() {
1846 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1847}
1848
1849
ager@chromium.org7c537e22008-10-16 08:43:32 +00001850uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 ASSERT(index >= 0 && index < length());
1852 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1853}
1854
1855
ager@chromium.org7c537e22008-10-16 08:43:32 +00001856void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001857 ASSERT(index >= 0 && index < length());
1858 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1859}
1860
1861
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001862int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001863 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001864}
1865
1866
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001867int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001868 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869}
1870
1871
ager@chromium.org870a0b62008-11-04 11:43:05 +00001872String* ConsString::first() {
1873 return String::cast(READ_FIELD(this, kFirstOffset));
1874}
1875
1876
1877Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001878 return READ_FIELD(this, kFirstOffset);
1879}
1880
1881
ager@chromium.org870a0b62008-11-04 11:43:05 +00001882void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001884 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885}
1886
1887
ager@chromium.org870a0b62008-11-04 11:43:05 +00001888String* ConsString::second() {
1889 return String::cast(READ_FIELD(this, kSecondOffset));
1890}
1891
1892
1893Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 return READ_FIELD(this, kSecondOffset);
1895}
1896
1897
ager@chromium.org870a0b62008-11-04 11:43:05 +00001898void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001899 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001900 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901}
1902
1903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1905 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1906}
1907
1908
1909void ExternalAsciiString::set_resource(
1910 ExternalAsciiString::Resource* resource) {
1911 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1912}
1913
1914
1915ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1916 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1917}
1918
1919
1920void ExternalTwoByteString::set_resource(
1921 ExternalTwoByteString::Resource* resource) {
1922 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1923}
1924
1925
ager@chromium.orgac091b72010-05-05 07:34:42 +00001926void JSFunctionResultCache::MakeZeroSize() {
1927 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1928 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1929}
1930
1931
1932void JSFunctionResultCache::Clear() {
1933 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1934 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1935 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1936 MakeZeroSize();
1937}
1938
1939
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001940byte ByteArray::get(int index) {
1941 ASSERT(index >= 0 && index < this->length());
1942 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1943}
1944
1945
1946void ByteArray::set(int index, byte value) {
1947 ASSERT(index >= 0 && index < this->length());
1948 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1949}
1950
1951
1952int ByteArray::get_int(int index) {
1953 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1954 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1955}
1956
1957
1958ByteArray* ByteArray::FromDataStartAddress(Address address) {
1959 ASSERT_TAG_ALIGNED(address);
1960 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1961}
1962
1963
1964Address ByteArray::GetDataStartAddress() {
1965 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1966}
1967
1968
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001969uint8_t* PixelArray::external_pointer() {
1970 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1971 return reinterpret_cast<uint8_t*>(ptr);
1972}
1973
1974
1975void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1976 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1977 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1978}
1979
1980
1981uint8_t PixelArray::get(int index) {
1982 ASSERT((index >= 0) && (index < this->length()));
1983 uint8_t* ptr = external_pointer();
1984 return ptr[index];
1985}
1986
1987
1988void PixelArray::set(int index, uint8_t value) {
1989 ASSERT((index >= 0) && (index < this->length()));
1990 uint8_t* ptr = external_pointer();
1991 ptr[index] = value;
1992}
1993
1994
ager@chromium.org3811b432009-10-28 14:53:37 +00001995void* ExternalArray::external_pointer() {
1996 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1997 return reinterpret_cast<void*>(ptr);
1998}
1999
2000
2001void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2002 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2003 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2004}
2005
2006
2007int8_t ExternalByteArray::get(int index) {
2008 ASSERT((index >= 0) && (index < this->length()));
2009 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2010 return ptr[index];
2011}
2012
2013
2014void ExternalByteArray::set(int index, int8_t value) {
2015 ASSERT((index >= 0) && (index < this->length()));
2016 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2017 ptr[index] = value;
2018}
2019
2020
2021uint8_t ExternalUnsignedByteArray::get(int index) {
2022 ASSERT((index >= 0) && (index < this->length()));
2023 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2024 return ptr[index];
2025}
2026
2027
2028void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2029 ASSERT((index >= 0) && (index < this->length()));
2030 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2031 ptr[index] = value;
2032}
2033
2034
2035int16_t ExternalShortArray::get(int index) {
2036 ASSERT((index >= 0) && (index < this->length()));
2037 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2038 return ptr[index];
2039}
2040
2041
2042void ExternalShortArray::set(int index, int16_t value) {
2043 ASSERT((index >= 0) && (index < this->length()));
2044 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2045 ptr[index] = value;
2046}
2047
2048
2049uint16_t ExternalUnsignedShortArray::get(int index) {
2050 ASSERT((index >= 0) && (index < this->length()));
2051 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2052 return ptr[index];
2053}
2054
2055
2056void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2057 ASSERT((index >= 0) && (index < this->length()));
2058 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2059 ptr[index] = value;
2060}
2061
2062
2063int32_t ExternalIntArray::get(int index) {
2064 ASSERT((index >= 0) && (index < this->length()));
2065 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2066 return ptr[index];
2067}
2068
2069
2070void ExternalIntArray::set(int index, int32_t value) {
2071 ASSERT((index >= 0) && (index < this->length()));
2072 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2073 ptr[index] = value;
2074}
2075
2076
2077uint32_t ExternalUnsignedIntArray::get(int index) {
2078 ASSERT((index >= 0) && (index < this->length()));
2079 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2080 return ptr[index];
2081}
2082
2083
2084void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2085 ASSERT((index >= 0) && (index < this->length()));
2086 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2087 ptr[index] = value;
2088}
2089
2090
2091float ExternalFloatArray::get(int index) {
2092 ASSERT((index >= 0) && (index < this->length()));
2093 float* ptr = static_cast<float*>(external_pointer());
2094 return ptr[index];
2095}
2096
2097
2098void ExternalFloatArray::set(int index, float value) {
2099 ASSERT((index >= 0) && (index < this->length()));
2100 float* ptr = static_cast<float*>(external_pointer());
2101 ptr[index] = value;
2102}
2103
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002104
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002105int Map::visitor_id() {
2106 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2107}
2108
2109
2110void Map::set_visitor_id(int id) {
2111 ASSERT(0 <= id && id < 256);
2112 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2113}
2114
ager@chromium.org3811b432009-10-28 14:53:37 +00002115
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002117 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2118}
2119
2120
2121int Map::inobject_properties() {
2122 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123}
2124
2125
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002126int Map::pre_allocated_property_fields() {
2127 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2128}
2129
2130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002132 int instance_size = map->instance_size();
2133 if (instance_size != kVariableSizeSentinel) return instance_size;
2134 // We can ignore the "symbol" bit becase it is only set for symbols
2135 // and implies a string type.
2136 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002137 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002139 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002141 if (instance_type == ASCII_STRING_TYPE) {
2142 return SeqAsciiString::SizeFor(
2143 reinterpret_cast<SeqAsciiString*>(this)->length());
2144 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002145 if (instance_type == BYTE_ARRAY_TYPE) {
2146 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2147 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002148 if (instance_type == STRING_TYPE) {
2149 return SeqTwoByteString::SizeFor(
2150 reinterpret_cast<SeqTwoByteString*>(this)->length());
2151 }
2152 ASSERT(instance_type == CODE_TYPE);
2153 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154}
2155
2156
2157void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002158 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002159 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160 ASSERT(0 <= value && value < 256);
2161 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2162}
2163
2164
ager@chromium.org7c537e22008-10-16 08:43:32 +00002165void Map::set_inobject_properties(int value) {
2166 ASSERT(0 <= value && value < 256);
2167 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2168}
2169
2170
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002171void Map::set_pre_allocated_property_fields(int value) {
2172 ASSERT(0 <= value && value < 256);
2173 WRITE_BYTE_FIELD(this,
2174 kPreAllocatedPropertyFieldsOffset,
2175 static_cast<byte>(value));
2176}
2177
2178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179InstanceType Map::instance_type() {
2180 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2181}
2182
2183
2184void Map::set_instance_type(InstanceType value) {
2185 ASSERT(0 <= value && value < 256);
2186 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2187}
2188
2189
2190int Map::unused_property_fields() {
2191 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2192}
2193
2194
2195void Map::set_unused_property_fields(int value) {
2196 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2197}
2198
2199
2200byte Map::bit_field() {
2201 return READ_BYTE_FIELD(this, kBitFieldOffset);
2202}
2203
2204
2205void Map::set_bit_field(byte value) {
2206 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2207}
2208
2209
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002210byte Map::bit_field2() {
2211 return READ_BYTE_FIELD(this, kBitField2Offset);
2212}
2213
2214
2215void Map::set_bit_field2(byte value) {
2216 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2217}
2218
2219
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002220void Map::set_non_instance_prototype(bool value) {
2221 if (value) {
2222 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2223 } else {
2224 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2225 }
2226}
2227
2228
2229bool Map::has_non_instance_prototype() {
2230 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2231}
2232
2233
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002234void Map::set_function_with_prototype(bool value) {
2235 if (value) {
2236 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2237 } else {
2238 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2239 }
2240}
2241
2242
2243bool Map::function_with_prototype() {
2244 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2245}
2246
2247
ager@chromium.org870a0b62008-11-04 11:43:05 +00002248void Map::set_is_access_check_needed(bool access_check_needed) {
2249 if (access_check_needed) {
2250 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2251 } else {
2252 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2253 }
2254}
2255
2256
2257bool Map::is_access_check_needed() {
2258 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2259}
2260
2261
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002262void Map::set_is_extensible(bool value) {
2263 if (value) {
2264 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2265 } else {
2266 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2267 }
2268}
2269
2270bool Map::is_extensible() {
2271 return ((1 << kIsExtensible) & bit_field2()) != 0;
2272}
2273
2274
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002275void Map::set_attached_to_shared_function_info(bool value) {
2276 if (value) {
2277 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2278 } else {
2279 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2280 }
2281}
2282
2283bool Map::attached_to_shared_function_info() {
2284 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2285}
2286
2287
2288void Map::set_is_shared(bool value) {
2289 if (value) {
2290 set_bit_field2(bit_field2() | (1 << kIsShared));
2291 } else {
2292 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2293 }
2294}
2295
2296bool Map::is_shared() {
2297 return ((1 << kIsShared) & bit_field2()) != 0;
2298}
2299
2300
2301JSFunction* Map::unchecked_constructor() {
2302 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2303}
2304
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002305
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002306Code::Flags Code::flags() {
2307 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2308}
2309
2310
2311void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002312 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002314 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2315 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002316 ExtractArgumentsCountFromFlags(flags) >= 0);
2317 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2318}
2319
2320
2321Code::Kind Code::kind() {
2322 return ExtractKindFromFlags(flags());
2323}
2324
2325
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002326InLoopFlag Code::ic_in_loop() {
2327 return ExtractICInLoopFromFlags(flags());
2328}
2329
2330
kasper.lund7276f142008-07-30 08:49:36 +00002331InlineCacheState Code::ic_state() {
2332 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 // Only allow uninitialized or debugger states for non-IC code
2334 // objects. This is used in the debugger to determine whether or not
2335 // a call to code object has been replaced with a debug break call.
2336 ASSERT(is_inline_cache_stub() ||
2337 result == UNINITIALIZED ||
2338 result == DEBUG_BREAK ||
2339 result == DEBUG_PREPARE_STEP_IN);
2340 return result;
2341}
2342
2343
2344PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002345 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002346 return ExtractTypeFromFlags(flags());
2347}
2348
2349
2350int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002351 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002352 return ExtractArgumentsCountFromFlags(flags());
2353}
2354
2355
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002356int Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002357 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002358 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002359}
2360
2361
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002362void Code::set_major_key(int major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002363 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002364 ASSERT(0 <= major && major < 256);
2365 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366}
2367
2368
2369bool Code::is_inline_cache_stub() {
2370 Kind kind = this->kind();
2371 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2372}
2373
2374
2375Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002376 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002377 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002378 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002379 int argc,
2380 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381 // Compute the bit mask.
2382 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002383 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002384 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385 bits |= type << kFlagsTypeShift;
2386 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002387 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388 // Cast to flags and validate result before returning it.
2389 Flags result = static_cast<Flags>(bits);
2390 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002391 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002392 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393 ASSERT(ExtractTypeFromFlags(result) == type);
2394 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2395 return result;
2396}
2397
2398
2399Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2400 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002401 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002402 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002404 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405}
2406
2407
2408Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2409 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2410 return static_cast<Kind>(bits);
2411}
2412
2413
kasper.lund7276f142008-07-30 08:49:36 +00002414InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2415 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 return static_cast<InlineCacheState>(bits);
2417}
2418
2419
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002420InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2421 int bits = (flags & kFlagsICInLoopMask);
2422 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2423}
2424
2425
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2427 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2428 return static_cast<PropertyType>(bits);
2429}
2430
2431
2432int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2433 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2434}
2435
2436
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002437InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2438 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2439 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2440}
2441
2442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2444 int bits = flags & ~kFlagsTypeMask;
2445 return static_cast<Flags>(bits);
2446}
2447
2448
ager@chromium.org8bb60582008-12-11 12:02:20 +00002449Code* Code::GetCodeFromTargetAddress(Address address) {
2450 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2451 // GetCodeFromTargetAddress might be called when marking objects during mark
2452 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2453 // Code::cast. Code::cast does not work when the object's map is
2454 // marked.
2455 Code* result = reinterpret_cast<Code*>(code);
2456 return result;
2457}
2458
2459
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002460Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2461 return HeapObject::
2462 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2463}
2464
2465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466Object* Map::prototype() {
2467 return READ_FIELD(this, kPrototypeOffset);
2468}
2469
2470
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002471void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002472 ASSERT(value->IsNull() || value->IsJSObject());
2473 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002474 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475}
2476
2477
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002478Object* Map::GetFastElementsMap() {
2479 if (has_fast_elements()) return this;
2480 Object* obj = CopyDropTransitions();
2481 if (obj->IsFailure()) return obj;
2482 Map* new_map = Map::cast(obj);
2483 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002484 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002485 return new_map;
2486}
2487
2488
2489Object* Map::GetSlowElementsMap() {
2490 if (!has_fast_elements()) return this;
2491 Object* obj = CopyDropTransitions();
2492 if (obj->IsFailure()) return obj;
2493 Map* new_map = Map::cast(obj);
2494 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002495 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002496 return new_map;
2497}
2498
2499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002500ACCESSORS(Map, instance_descriptors, DescriptorArray,
2501 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002502ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002503ACCESSORS(Map, constructor, Object, kConstructorOffset)
2504
2505ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2506ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2507
2508ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2509ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002510ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002511
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002512ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002513
2514ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2515ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2516ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2517ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2518ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002519ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002520
2521ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2522ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2523ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2524
2525ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2526ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2527ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2528ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2529ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2530ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2531
2532ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2533ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2534
2535ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2536ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2537
2538ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2539ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002540ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2541 kPropertyAccessorsOffset)
2542ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2543 kPrototypeTemplateOffset)
2544ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2545ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2546 kNamedPropertyHandlerOffset)
2547ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2548 kIndexedPropertyHandlerOffset)
2549ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2550 kInstanceTemplateOffset)
2551ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2552ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002553ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2554 kInstanceCallHandlerOffset)
2555ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2556 kAccessCheckInfoOffset)
2557ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2558
2559ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002560ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2561 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002562
2563ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2564ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2565
2566ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2567
2568ACCESSORS(Script, source, Object, kSourceOffset)
2569ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002570ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002571ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2572ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002573ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002574ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2576ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002577ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002578ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002579ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002580ACCESSORS(Script, eval_from_instructions_offset, Smi,
2581 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002583#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002584ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2585ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2586ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2587ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2588
2589ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2590ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2591ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2592ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002593#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002594
2595ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002596ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002597ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002598ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2599 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002600ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002601ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2602ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002603ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002604ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2605 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002606
2607BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2608 kHiddenPrototypeBit)
2609BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2610BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2611 kNeedsAccessCheckBit)
2612BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2613 kIsExpressionBit)
2614BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2615 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002616BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002617 has_only_simple_this_property_assignments,
2618 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002619BOOL_ACCESSORS(SharedFunctionInfo,
2620 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002621 try_full_codegen,
2622 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002623BOOL_ACCESSORS(SharedFunctionInfo,
2624 compiler_hints,
2625 allows_lazy_compilation,
2626 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002627
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002628
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002629#if V8_HOST_ARCH_32_BIT
2630SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2631SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002633SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002634 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002635SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2636SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002638SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2639SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002640 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002641SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002642 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002643SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002644 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002645#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002646
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002647#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2648 int holder::name() { \
2649 int value = READ_INT_FIELD(this, offset); \
2650 ASSERT(kHeapObjectTag == 1); \
2651 ASSERT((value & kHeapObjectTag) == 0); \
2652 return value >> 1; \
2653 } \
2654 void holder::set_##name(int value) { \
2655 ASSERT(kHeapObjectTag == 1); \
2656 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2657 (value & 0xC0000000) == 0x000000000); \
2658 WRITE_INT_FIELD(this, \
2659 offset, \
2660 (value << 1) & ~kHeapObjectTag); \
2661 }
2662
2663#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2664 INT_ACCESSORS(holder, name, offset)
2665
2666
2667
2668PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2669PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2670 kFormalParameterCountOffset)
2671
2672PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2673 kExpectedNofPropertiesOffset)
2674PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2675
2676PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2677 kStartPositionAndTypeOffset)
2678PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2679
2680PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2681 kFunctionTokenPositionOffset)
2682PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2683 kCompilerHintsOffset)
2684
2685PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2686 kThisPropertyAssignmentsCountOffset)
2687#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002688
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002689
2690int SharedFunctionInfo::construction_count() {
2691 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2692}
2693
2694
2695void SharedFunctionInfo::set_construction_count(int value) {
2696 ASSERT(0 <= value && value < 256);
2697 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2698}
2699
2700
2701bool SharedFunctionInfo::live_objects_may_exist() {
2702 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2703}
2704
2705
2706void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2707 if (value) {
2708 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2709 } else {
2710 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2711 }
2712}
2713
2714
2715bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2716 return initial_map() != Heap::undefined_value();
2717}
2718
2719
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002720ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2721ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2722
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002723bool Script::HasValidSource() {
2724 Object* src = this->source();
2725 if (!src->IsString()) return true;
2726 String* src_str = String::cast(src);
2727 if (!StringShape(src_str).IsExternal()) return true;
2728 if (src_str->IsAsciiRepresentation()) {
2729 return ExternalAsciiString::cast(src)->resource() != NULL;
2730 } else if (src_str->IsTwoByteRepresentation()) {
2731 return ExternalTwoByteString::cast(src)->resource() != NULL;
2732 }
2733 return true;
2734}
2735
2736
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002737void SharedFunctionInfo::DontAdaptArguments() {
2738 ASSERT(code()->kind() == Code::BUILTIN);
2739 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2740}
2741
2742
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002743int SharedFunctionInfo::start_position() {
2744 return start_position_and_type() >> kStartPositionShift;
2745}
2746
2747
2748void SharedFunctionInfo::set_start_position(int start_position) {
2749 set_start_position_and_type((start_position << kStartPositionShift)
2750 | (start_position_and_type() & ~kStartPositionMask));
2751}
2752
2753
2754Code* SharedFunctionInfo::code() {
2755 return Code::cast(READ_FIELD(this, kCodeOffset));
2756}
2757
2758
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002759Code* SharedFunctionInfo::unchecked_code() {
2760 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2761}
2762
2763
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002764void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002765 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002766 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002767}
2768
2769
ager@chromium.orgb5737492010-07-15 09:29:43 +00002770SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2771 return reinterpret_cast<SerializedScopeInfo*>(
2772 READ_FIELD(this, kScopeInfoOffset));
2773}
2774
2775
2776void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2777 WriteBarrierMode mode) {
2778 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2779 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2780}
2781
2782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002784 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785}
2786
2787
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002788bool SharedFunctionInfo::IsApiFunction() {
2789 return function_data()->IsFunctionTemplateInfo();
2790}
2791
2792
2793FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2794 ASSERT(IsApiFunction());
2795 return FunctionTemplateInfo::cast(function_data());
2796}
2797
2798
2799bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002800 return function_data()->IsSmi();
2801}
2802
2803
2804int SharedFunctionInfo::custom_call_generator_id() {
2805 ASSERT(HasCustomCallGenerator());
2806 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002807}
2808
2809
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002810int SharedFunctionInfo::code_age() {
2811 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2812}
2813
2814
2815void SharedFunctionInfo::set_code_age(int code_age) {
2816 set_compiler_hints(compiler_hints() |
2817 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2818}
2819
2820
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002821bool JSFunction::IsBuiltin() {
2822 return context()->global()->IsJSBuiltinsObject();
2823}
2824
2825
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002826Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002827 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002828}
2829
2830
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002831Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002832 return reinterpret_cast<Code*>(
2833 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002834}
2835
2836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002837void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002838 // Skip the write barrier because code is never in new space.
2839 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002840 Address entry = value->entry();
2841 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842}
2843
2844
2845Context* JSFunction::context() {
2846 return Context::cast(READ_FIELD(this, kContextOffset));
2847}
2848
2849
2850Object* JSFunction::unchecked_context() {
2851 return READ_FIELD(this, kContextOffset);
2852}
2853
2854
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002855SharedFunctionInfo* JSFunction::unchecked_shared() {
2856 return reinterpret_cast<SharedFunctionInfo*>(
2857 READ_FIELD(this, kSharedFunctionInfoOffset));
2858}
2859
2860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002861void JSFunction::set_context(Object* value) {
2862 ASSERT(value == Heap::undefined_value() || value->IsContext());
2863 WRITE_FIELD(this, kContextOffset, value);
2864 WRITE_BARRIER(this, kContextOffset);
2865}
2866
2867ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2868 kPrototypeOrInitialMapOffset)
2869
2870
2871Map* JSFunction::initial_map() {
2872 return Map::cast(prototype_or_initial_map());
2873}
2874
2875
2876void JSFunction::set_initial_map(Map* value) {
2877 set_prototype_or_initial_map(value);
2878}
2879
2880
2881bool JSFunction::has_initial_map() {
2882 return prototype_or_initial_map()->IsMap();
2883}
2884
2885
2886bool JSFunction::has_instance_prototype() {
2887 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2888}
2889
2890
2891bool JSFunction::has_prototype() {
2892 return map()->has_non_instance_prototype() || has_instance_prototype();
2893}
2894
2895
2896Object* JSFunction::instance_prototype() {
2897 ASSERT(has_instance_prototype());
2898 if (has_initial_map()) return initial_map()->prototype();
2899 // When there is no initial map and the prototype is a JSObject, the
2900 // initial map field is used for the prototype field.
2901 return prototype_or_initial_map();
2902}
2903
2904
2905Object* JSFunction::prototype() {
2906 ASSERT(has_prototype());
2907 // If the function's prototype property has been set to a non-JSObject
2908 // value, that value is stored in the constructor field of the map.
2909 if (map()->has_non_instance_prototype()) return map()->constructor();
2910 return instance_prototype();
2911}
2912
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002913bool JSFunction::should_have_prototype() {
2914 return map()->function_with_prototype();
2915}
2916
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917
2918bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002919 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002920}
2921
2922
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002923int JSFunction::NumberOfLiterals() {
2924 return literals()->length();
2925}
2926
2927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2929 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002930 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002931}
2932
2933
2934void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2935 Object* value) {
2936 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002937 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2938 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2939}
2940
2941
2942Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2943 ASSERT(0 <= id && id < kJSBuiltinsCount);
2944 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2945}
2946
2947
2948void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2949 Code* value) {
2950 ASSERT(0 <= id && id < kJSBuiltinsCount);
2951 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2952 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002953}
2954
2955
2956Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002957 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002958}
2959
2960
2961void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002962 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002963}
2964
2965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002966ACCESSORS(JSValue, value, Object, kValueOffset)
2967
2968
2969JSValue* JSValue::cast(Object* obj) {
2970 ASSERT(obj->IsJSValue());
2971 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2972 return reinterpret_cast<JSValue*>(obj);
2973}
2974
2975
2976INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002977ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978
2979
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002980byte* Code::instruction_start() {
2981 return FIELD_ADDR(this, kHeaderSize);
2982}
2983
2984
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002985byte* Code::instruction_end() {
2986 return instruction_start() + instruction_size();
2987}
2988
2989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002991 return RoundUp(instruction_size(), kObjectAlignment);
2992}
2993
2994
2995ByteArray* Code::unchecked_relocation_info() {
2996 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002997}
2998
2999
3000byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003001 return unchecked_relocation_info()->GetDataStartAddress();
3002}
3003
3004
3005int Code::relocation_size() {
3006 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003007}
3008
3009
3010byte* Code::entry() {
3011 return instruction_start();
3012}
3013
3014
3015bool Code::contains(byte* pc) {
3016 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003017 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003018}
3019
3020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003021ACCESSORS(JSArray, length, Object, kLengthOffset)
3022
3023
ager@chromium.org236ad962008-09-25 09:45:57 +00003024ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003025
3026
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003027JSRegExp::Type JSRegExp::TypeTag() {
3028 Object* data = this->data();
3029 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3030 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3031 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003032}
3033
3034
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003035int JSRegExp::CaptureCount() {
3036 switch (TypeTag()) {
3037 case ATOM:
3038 return 0;
3039 case IRREGEXP:
3040 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3041 default:
3042 UNREACHABLE();
3043 return -1;
3044 }
3045}
3046
3047
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003048JSRegExp::Flags JSRegExp::GetFlags() {
3049 ASSERT(this->data()->IsFixedArray());
3050 Object* data = this->data();
3051 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3052 return Flags(smi->value());
3053}
3054
3055
3056String* JSRegExp::Pattern() {
3057 ASSERT(this->data()->IsFixedArray());
3058 Object* data = this->data();
3059 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3060 return pattern;
3061}
3062
3063
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003064Object* JSRegExp::DataAt(int index) {
3065 ASSERT(TypeTag() != NOT_COMPILED);
3066 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003067}
3068
3069
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003070void JSRegExp::SetDataAt(int index, Object* value) {
3071 ASSERT(TypeTag() != NOT_COMPILED);
3072 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3073 FixedArray::cast(data())->set(index, value);
3074}
3075
3076
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003077JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003078 if (map()->has_fast_elements()) {
3079 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3080 elements()->map() == Heap::fixed_cow_array_map());
3081 return FAST_ELEMENTS;
3082 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003083 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003084 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003085 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3086 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003087 ASSERT(array->IsDictionary());
3088 return DICTIONARY_ELEMENTS;
3089 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003090 if (array->IsExternalArray()) {
3091 switch (array->map()->instance_type()) {
3092 case EXTERNAL_BYTE_ARRAY_TYPE:
3093 return EXTERNAL_BYTE_ELEMENTS;
3094 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3095 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3096 case EXTERNAL_SHORT_ARRAY_TYPE:
3097 return EXTERNAL_SHORT_ELEMENTS;
3098 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3099 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3100 case EXTERNAL_INT_ARRAY_TYPE:
3101 return EXTERNAL_INT_ELEMENTS;
3102 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3103 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3104 default:
3105 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3106 return EXTERNAL_FLOAT_ELEMENTS;
3107 }
3108 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003109 ASSERT(array->IsPixelArray());
3110 return PIXEL_ELEMENTS;
3111}
3112
3113
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003114bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003115 return GetElementsKind() == FAST_ELEMENTS;
3116}
3117
3118
3119bool JSObject::HasDictionaryElements() {
3120 return GetElementsKind() == DICTIONARY_ELEMENTS;
3121}
3122
3123
3124bool JSObject::HasPixelElements() {
3125 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003126}
3127
3128
ager@chromium.org3811b432009-10-28 14:53:37 +00003129bool JSObject::HasExternalArrayElements() {
3130 return (HasExternalByteElements() ||
3131 HasExternalUnsignedByteElements() ||
3132 HasExternalShortElements() ||
3133 HasExternalUnsignedShortElements() ||
3134 HasExternalIntElements() ||
3135 HasExternalUnsignedIntElements() ||
3136 HasExternalFloatElements());
3137}
3138
3139
3140bool JSObject::HasExternalByteElements() {
3141 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3142}
3143
3144
3145bool JSObject::HasExternalUnsignedByteElements() {
3146 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3147}
3148
3149
3150bool JSObject::HasExternalShortElements() {
3151 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3152}
3153
3154
3155bool JSObject::HasExternalUnsignedShortElements() {
3156 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3157}
3158
3159
3160bool JSObject::HasExternalIntElements() {
3161 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3162}
3163
3164
3165bool JSObject::HasExternalUnsignedIntElements() {
3166 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3167}
3168
3169
3170bool JSObject::HasExternalFloatElements() {
3171 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3172}
3173
3174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003175bool JSObject::HasNamedInterceptor() {
3176 return map()->has_named_interceptor();
3177}
3178
3179
3180bool JSObject::HasIndexedInterceptor() {
3181 return map()->has_indexed_interceptor();
3182}
3183
3184
ager@chromium.org5c838252010-02-19 08:53:10 +00003185bool JSObject::AllowsSetElementsLength() {
3186 bool result = elements()->IsFixedArray();
3187 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3188 return result;
3189}
3190
3191
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003192Object* JSObject::EnsureWritableFastElements() {
3193 ASSERT(HasFastElements());
3194 FixedArray* elems = FixedArray::cast(elements());
3195 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003196 Object* writable_elems = Heap::CopyFixedArrayWithMap(elems,
3197 Heap::fixed_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003198 if (writable_elems->IsFailure()) return writable_elems;
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003199 set_elements(FixedArray::cast(writable_elems));
3200 Counters::cow_arrays_converted.Increment();
3201 return writable_elems;
3202}
3203
3204
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003205StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003207 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208}
3209
3210
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003211NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003212 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003213 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003214}
3215
3216
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003217bool String::IsHashFieldComputed(uint32_t field) {
3218 return (field & kHashNotComputedMask) == 0;
3219}
3220
3221
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003222bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003223 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003224}
3225
3226
3227uint32_t String::Hash() {
3228 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003229 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003230 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003231 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003232 return ComputeAndSetHash();
3233}
3234
3235
ager@chromium.org7c537e22008-10-16 08:43:32 +00003236StringHasher::StringHasher(int length)
3237 : length_(length),
3238 raw_running_hash_(0),
3239 array_index_(0),
3240 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3241 is_first_char_(true),
3242 is_valid_(true) { }
3243
3244
3245bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003246 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003247}
3248
3249
3250void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003251 // Use the Jenkins one-at-a-time hash function to update the hash
3252 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003253 raw_running_hash_ += c;
3254 raw_running_hash_ += (raw_running_hash_ << 10);
3255 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003256 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003257 if (is_array_index_) {
3258 if (c < '0' || c > '9') {
3259 is_array_index_ = false;
3260 } else {
3261 int d = c - '0';
3262 if (is_first_char_) {
3263 is_first_char_ = false;
3264 if (c == '0' && length_ > 1) {
3265 is_array_index_ = false;
3266 return;
3267 }
3268 }
3269 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3270 is_array_index_ = false;
3271 } else {
3272 array_index_ = array_index_ * 10 + d;
3273 }
3274 }
3275 }
3276}
3277
3278
3279void StringHasher::AddCharacterNoIndex(uc32 c) {
3280 ASSERT(!is_array_index());
3281 raw_running_hash_ += c;
3282 raw_running_hash_ += (raw_running_hash_ << 10);
3283 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3284}
3285
3286
3287uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003288 // Get the calculated raw hash value and do some more bit ops to distribute
3289 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003290 uint32_t result = raw_running_hash_;
3291 result += (result << 3);
3292 result ^= (result >> 11);
3293 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003294 if (result == 0) {
3295 result = 27;
3296 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003297 return result;
3298}
3299
3300
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003301bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003302 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003303 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3304 return false;
3305 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003306 return SlowAsArrayIndex(index);
3307}
3308
3309
3310Object* JSObject::GetPrototype() {
3311 return JSObject::cast(this)->map()->prototype();
3312}
3313
3314
3315PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3316 return GetPropertyAttributeWithReceiver(this, key);
3317}
3318
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003319// TODO(504): this may be useful in other places too where JSGlobalProxy
3320// is used.
3321Object* JSObject::BypassGlobalProxy() {
3322 if (IsJSGlobalProxy()) {
3323 Object* proto = GetPrototype();
3324 if (proto->IsNull()) return Heap::undefined_value();
3325 ASSERT(proto->IsJSGlobalObject());
3326 return proto;
3327 }
3328 return this;
3329}
3330
3331
3332bool JSObject::HasHiddenPropertiesObject() {
3333 ASSERT(!IsJSGlobalProxy());
3334 return GetPropertyAttributePostInterceptor(this,
3335 Heap::hidden_symbol(),
3336 false) != ABSENT;
3337}
3338
3339
3340Object* JSObject::GetHiddenPropertiesObject() {
3341 ASSERT(!IsJSGlobalProxy());
3342 PropertyAttributes attributes;
3343 return GetLocalPropertyPostInterceptor(this,
3344 Heap::hidden_symbol(),
3345 &attributes);
3346}
3347
3348
3349Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3350 ASSERT(!IsJSGlobalProxy());
3351 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3352 hidden_obj,
3353 DONT_ENUM);
3354}
3355
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003356
3357bool JSObject::HasElement(uint32_t index) {
3358 return HasElementWithReceiver(this, index);
3359}
3360
3361
3362bool AccessorInfo::all_can_read() {
3363 return BooleanBit::get(flag(), kAllCanReadBit);
3364}
3365
3366
3367void AccessorInfo::set_all_can_read(bool value) {
3368 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3369}
3370
3371
3372bool AccessorInfo::all_can_write() {
3373 return BooleanBit::get(flag(), kAllCanWriteBit);
3374}
3375
3376
3377void AccessorInfo::set_all_can_write(bool value) {
3378 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3379}
3380
3381
ager@chromium.org870a0b62008-11-04 11:43:05 +00003382bool AccessorInfo::prohibits_overwriting() {
3383 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3384}
3385
3386
3387void AccessorInfo::set_prohibits_overwriting(bool value) {
3388 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3389}
3390
3391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392PropertyAttributes AccessorInfo::property_attributes() {
3393 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3394}
3395
3396
3397void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3398 ASSERT(AttributesField::is_valid(attributes));
3399 int rest_value = flag()->value() & ~AttributesField::mask();
3400 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3401}
3402
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003403template<typename Shape, typename Key>
3404void Dictionary<Shape, Key>::SetEntry(int entry,
3405 Object* key,
3406 Object* value,
3407 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003408 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003409 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003410 AssertNoAllocation no_gc;
3411 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003412 FixedArray::set(index, key, mode);
3413 FixedArray::set(index+1, value, mode);
3414 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003415}
3416
3417
3418void Map::ClearCodeCache() {
3419 // No write barrier is needed since empty_fixed_array is not in new space.
3420 // Please note this function is used during marking:
3421 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003422 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3423 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003424}
3425
3426
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003427void JSArray::EnsureSize(int required_size) {
3428 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003429 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003430 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3431 if (elts->length() < required_size) {
3432 // Doubling in size would be overkill, but leave some slack to avoid
3433 // constantly growing.
3434 Expand(required_size + (required_size >> 3));
3435 // It's a performance benefit to keep a frequently used array in new-space.
3436 } else if (!Heap::new_space()->Contains(elts) &&
3437 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3438 // Expand will allocate a new backing store in new space even if the size
3439 // we asked for isn't larger than what we had before.
3440 Expand(required_size);
3441 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003442}
3443
3444
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003445void JSArray::set_length(Smi* length) {
3446 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3447}
3448
3449
ager@chromium.org7c537e22008-10-16 08:43:32 +00003450void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003451 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003452 set_elements(storage);
3453}
3454
3455
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003456Object* FixedArray::Copy() {
3457 if (length() == 0) return this;
3458 return Heap::CopyFixedArray(this);
3459}
3460
3461
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003462int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3463 return map->instance_size();
3464}
3465
3466
3467void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3468 v->VisitExternalReference(
3469 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3470}
3471
3472
3473template<typename StaticVisitor>
3474void Proxy::ProxyIterateBody() {
3475 StaticVisitor::VisitExternalReference(
3476 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3477}
3478
3479
3480void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3481 typedef v8::String::ExternalAsciiStringResource Resource;
3482 v->VisitExternalAsciiString(
3483 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3484}
3485
3486
3487template<typename StaticVisitor>
3488void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3489 typedef v8::String::ExternalAsciiStringResource Resource;
3490 StaticVisitor::VisitExternalAsciiString(
3491 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3492}
3493
3494
3495void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3496 typedef v8::String::ExternalStringResource Resource;
3497 v->VisitExternalTwoByteString(
3498 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3499}
3500
3501
3502template<typename StaticVisitor>
3503void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3504 typedef v8::String::ExternalStringResource Resource;
3505 StaticVisitor::VisitExternalTwoByteString(
3506 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3507}
3508
3509#define SLOT_ADDR(obj, offset) \
3510 reinterpret_cast<Object**>((obj)->address() + offset)
3511
3512template<int start_offset, int end_offset, int size>
3513void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3514 HeapObject* obj,
3515 ObjectVisitor* v) {
3516 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3517}
3518
3519
3520template<int start_offset>
3521void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3522 int object_size,
3523 ObjectVisitor* v) {
3524 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3525}
3526
3527#undef SLOT_ADDR
3528
3529
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003530#undef CAST_ACCESSOR
3531#undef INT_ACCESSORS
3532#undef SMI_ACCESSORS
3533#undef ACCESSORS
3534#undef FIELD_ADDR
3535#undef READ_FIELD
3536#undef WRITE_FIELD
3537#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003538#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003539#undef READ_MEMADDR_FIELD
3540#undef WRITE_MEMADDR_FIELD
3541#undef READ_DOUBLE_FIELD
3542#undef WRITE_DOUBLE_FIELD
3543#undef READ_INT_FIELD
3544#undef WRITE_INT_FIELD
3545#undef READ_SHORT_FIELD
3546#undef WRITE_SHORT_FIELD
3547#undef READ_BYTE_FIELD
3548#undef WRITE_BYTE_FIELD
3549
3550
3551} } // namespace v8::internal
3552
3553#endif // V8_OBJECTS_INL_H_