blob: f63d6725ec2981afdf13b294c8a7de8a76d51f31 [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
847int Failure::requested() const {
848 const int kShiftBits =
849 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
850 STATIC_ASSERT(kShiftBits >= 0);
851 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000852 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853}
854
855
856AllocationSpace Failure::allocation_space() const {
857 ASSERT_EQ(RETRY_AFTER_GC, type());
858 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
859 & kSpaceTagMask);
860}
861
862
863Failure* Failure::InternalError() {
864 return Construct(INTERNAL_ERROR);
865}
866
867
868Failure* Failure::Exception() {
869 return Construct(EXCEPTION);
870}
871
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000872
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000873Failure* Failure::OutOfMemoryException() {
874 return Construct(OUT_OF_MEMORY_EXCEPTION);
875}
876
877
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000878intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000879 return static_cast<intptr_t>(
880 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000881}
882
883
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000884Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000885 // Assert that the space encoding fits in the three bytes allotted for it.
886 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000887 uintptr_t requested =
888 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
889 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000890 if (((requested << tag_bits) >> tag_bits) != requested) {
891 // No room for entire requested size in the bits. Round down to
892 // maximally representable size.
893 requested = static_cast<intptr_t>(
894 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
895 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000896 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000897 return Construct(RETRY_AFTER_GC, value);
898}
899
900
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000901Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000902 uintptr_t info =
903 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000904 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000905 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906}
907
908
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000909bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910#ifdef DEBUG
911 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
912#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000913
914#ifdef V8_TARGET_ARCH_X64
915 // To be representable as a long smi, the value must be a 32-bit integer.
916 bool result = (value == static_cast<int32_t>(value));
917#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000918 // To be representable as an tagged small integer, the two
919 // most-significant bits of 'value' must be either 00 or 11 due to
920 // sign-extension. To check this we add 01 to the two
921 // most-significant bits, and check if the most-significant bit is 0
922 //
923 // CAUTION: The original code below:
924 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
925 // may lead to incorrect results according to the C language spec, and
926 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
927 // compiler may produce undefined results in case of signed integer
928 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000929 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000930#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000931 ASSERT(result == in_range);
932 return result;
933}
934
935
kasper.lund7276f142008-07-30 08:49:36 +0000936MapWord MapWord::FromMap(Map* map) {
937 return MapWord(reinterpret_cast<uintptr_t>(map));
938}
939
940
941Map* MapWord::ToMap() {
942 return reinterpret_cast<Map*>(value_);
943}
944
945
946bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000947 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000948}
949
950
951MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000952 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
953 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000954}
955
956
957HeapObject* MapWord::ToForwardingAddress() {
958 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000959 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000960}
961
962
963bool MapWord::IsMarked() {
964 return (value_ & kMarkingMask) == 0;
965}
966
967
968void MapWord::SetMark() {
969 value_ &= ~kMarkingMask;
970}
971
972
973void MapWord::ClearMark() {
974 value_ |= kMarkingMask;
975}
976
977
978bool MapWord::IsOverflowed() {
979 return (value_ & kOverflowMask) != 0;
980}
981
982
983void MapWord::SetOverflow() {
984 value_ |= kOverflowMask;
985}
986
987
988void MapWord::ClearOverflow() {
989 value_ &= ~kOverflowMask;
990}
991
992
993MapWord MapWord::EncodeAddress(Address map_address, int offset) {
994 // Offset is the distance in live bytes from the first live object in the
995 // same page. The offset between two objects in the same page should not
996 // exceed the object area size of a page.
997 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
998
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000999 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001000 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1001
1002 Page* map_page = Page::FromAddress(map_address);
1003 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1004
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001005 uintptr_t map_page_offset =
1006 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001007
1008 uintptr_t encoding =
1009 (compact_offset << kForwardingOffsetShift) |
1010 (map_page_offset << kMapPageOffsetShift) |
1011 (map_page->mc_page_index << kMapPageIndexShift);
1012 return MapWord(encoding);
1013}
1014
1015
1016Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001017 int map_page_index =
1018 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001019 ASSERT_MAP_PAGE_INDEX(map_page_index);
1020
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001021 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001022 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1023 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001024
1025 return (map_space->PageAddress(map_page_index) + map_page_offset);
1026}
1027
1028
1029int MapWord::DecodeOffset() {
1030 // The offset field is represented in the kForwardingOffsetBits
1031 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001032 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1033 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1034 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001035}
1036
1037
1038MapWord MapWord::FromEncodedAddress(Address address) {
1039 return MapWord(reinterpret_cast<uintptr_t>(address));
1040}
1041
1042
1043Address MapWord::ToEncodedAddress() {
1044 return reinterpret_cast<Address>(value_);
1045}
1046
1047
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048#ifdef DEBUG
1049void HeapObject::VerifyObjectField(int offset) {
1050 VerifyPointer(READ_FIELD(this, offset));
1051}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001052
1053void HeapObject::VerifySmiField(int offset) {
1054 ASSERT(READ_FIELD(this, offset)->IsSmi());
1055}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056#endif
1057
1058
1059Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001060 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061}
1062
1063
1064void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001065 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066}
1067
1068
kasper.lund7276f142008-07-30 08:49:36 +00001069MapWord HeapObject::map_word() {
1070 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1071}
1072
1073
1074void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001075 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001076 // here.
1077 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1078}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079
1080
1081HeapObject* HeapObject::FromAddress(Address address) {
1082 ASSERT_TAG_ALIGNED(address);
1083 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1084}
1085
1086
1087Address HeapObject::address() {
1088 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1089}
1090
1091
1092int HeapObject::Size() {
1093 return SizeFromMap(map());
1094}
1095
1096
1097void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1098 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1099 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1100}
1101
1102
1103void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1104 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1105}
1106
1107
kasper.lund7276f142008-07-30 08:49:36 +00001108bool HeapObject::IsMarked() {
1109 return map_word().IsMarked();
1110}
1111
1112
1113void HeapObject::SetMark() {
1114 ASSERT(!IsMarked());
1115 MapWord first_word = map_word();
1116 first_word.SetMark();
1117 set_map_word(first_word);
1118}
1119
1120
1121void HeapObject::ClearMark() {
1122 ASSERT(IsMarked());
1123 MapWord first_word = map_word();
1124 first_word.ClearMark();
1125 set_map_word(first_word);
1126}
1127
1128
1129bool HeapObject::IsOverflowed() {
1130 return map_word().IsOverflowed();
1131}
1132
1133
1134void HeapObject::SetOverflow() {
1135 MapWord first_word = map_word();
1136 first_word.SetOverflow();
1137 set_map_word(first_word);
1138}
1139
1140
1141void HeapObject::ClearOverflow() {
1142 ASSERT(IsOverflowed());
1143 MapWord first_word = map_word();
1144 first_word.ClearOverflow();
1145 set_map_word(first_word);
1146}
1147
1148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001149double HeapNumber::value() {
1150 return READ_DOUBLE_FIELD(this, kValueOffset);
1151}
1152
1153
1154void HeapNumber::set_value(double value) {
1155 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1156}
1157
1158
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001159int HeapNumber::get_exponent() {
1160 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1161 kExponentShift) - kExponentBias;
1162}
1163
1164
1165int HeapNumber::get_sign() {
1166 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1167}
1168
1169
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001170ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001171
1172
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001173HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001174 Object* array = READ_FIELD(this, kElementsOffset);
1175 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001176 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1177 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001178 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001179}
1180
1181
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001182void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001183 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001184 (value->map() == Heap::fixed_array_map() ||
1185 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001186 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001187 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1188 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001189 WRITE_FIELD(this, kElementsOffset, value);
1190 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1191}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192
1193
1194void JSObject::initialize_properties() {
1195 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1196 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1197}
1198
1199
1200void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001201 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1203 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1204}
1205
1206
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001207Object* JSObject::ResetElements() {
1208 Object* obj = map()->GetFastElementsMap();
1209 if (obj->IsFailure()) return obj;
1210 set_map(Map::cast(obj));
1211 initialize_elements();
1212 return this;
1213}
1214
1215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001216ACCESSORS(Oddball, to_string, String, kToStringOffset)
1217ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1218
1219
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001220Object* JSGlobalPropertyCell::value() {
1221 return READ_FIELD(this, kValueOffset);
1222}
1223
1224
1225void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1226 // The write barrier is not used for global property cells.
1227 ASSERT(!val->IsJSGlobalPropertyCell());
1228 WRITE_FIELD(this, kValueOffset, val);
1229}
1230
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001231
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001232int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001233 InstanceType type = map()->instance_type();
1234 // Check for the most common kind of JavaScript object before
1235 // falling into the generic switch. This speeds up the internal
1236 // field operations considerably on average.
1237 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1238 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001239 case JS_GLOBAL_PROXY_TYPE:
1240 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001241 case JS_GLOBAL_OBJECT_TYPE:
1242 return JSGlobalObject::kSize;
1243 case JS_BUILTINS_OBJECT_TYPE:
1244 return JSBuiltinsObject::kSize;
1245 case JS_FUNCTION_TYPE:
1246 return JSFunction::kSize;
1247 case JS_VALUE_TYPE:
1248 return JSValue::kSize;
1249 case JS_ARRAY_TYPE:
1250 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001251 case JS_REGEXP_TYPE:
1252 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001253 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001254 return JSObject::kHeaderSize;
1255 default:
1256 UNREACHABLE();
1257 return 0;
1258 }
1259}
1260
1261
1262int JSObject::GetInternalFieldCount() {
1263 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001264 // Make sure to adjust for the number of in-object properties. These
1265 // properties do contribute to the size, but are not internal fields.
1266 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1267 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001268}
1269
1270
1271Object* JSObject::GetInternalField(int index) {
1272 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001273 // Internal objects do follow immediately after the header, whereas in-object
1274 // properties are at the end of the object. Therefore there is no need
1275 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001276 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1277}
1278
1279
1280void JSObject::SetInternalField(int index, Object* value) {
1281 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001282 // Internal objects do follow immediately after the header, whereas in-object
1283 // properties are at the end of the object. Therefore there is no need
1284 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001285 int offset = GetHeaderSize() + (kPointerSize * index);
1286 WRITE_FIELD(this, offset, value);
1287 WRITE_BARRIER(this, offset);
1288}
1289
1290
ager@chromium.org7c537e22008-10-16 08:43:32 +00001291// Access fast-case object properties at index. The use of these routines
1292// is needed to correctly distinguish between properties stored in-object and
1293// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001294Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001295 // Adjust for the number of properties stored in the object.
1296 index -= map()->inobject_properties();
1297 if (index < 0) {
1298 int offset = map()->instance_size() + (index * kPointerSize);
1299 return READ_FIELD(this, offset);
1300 } else {
1301 ASSERT(index < properties()->length());
1302 return properties()->get(index);
1303 }
1304}
1305
1306
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001307Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001308 // Adjust for the number of properties stored in the object.
1309 index -= map()->inobject_properties();
1310 if (index < 0) {
1311 int offset = map()->instance_size() + (index * kPointerSize);
1312 WRITE_FIELD(this, offset, value);
1313 WRITE_BARRIER(this, offset);
1314 } else {
1315 ASSERT(index < properties()->length());
1316 properties()->set(index, value);
1317 }
1318 return value;
1319}
1320
1321
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001322Object* JSObject::InObjectPropertyAt(int index) {
1323 // Adjust for the number of properties stored in the object.
1324 index -= map()->inobject_properties();
1325 ASSERT(index < 0);
1326 int offset = map()->instance_size() + (index * kPointerSize);
1327 return READ_FIELD(this, offset);
1328}
1329
1330
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001331Object* JSObject::InObjectPropertyAtPut(int index,
1332 Object* value,
1333 WriteBarrierMode mode) {
1334 // Adjust for the number of properties stored in the object.
1335 index -= map()->inobject_properties();
1336 ASSERT(index < 0);
1337 int offset = map()->instance_size() + (index * kPointerSize);
1338 WRITE_FIELD(this, offset, value);
1339 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1340 return value;
1341}
1342
1343
1344
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001345void JSObject::InitializeBody(int object_size, Object* value) {
1346 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001347 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001348 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001349 }
1350}
1351
1352
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001353bool JSObject::HasFastProperties() {
1354 return !properties()->IsDictionary();
1355}
1356
1357
1358int JSObject::MaxFastProperties() {
1359 // Allow extra fast properties if the object has more than
1360 // kMaxFastProperties in-object properties. When this is the case,
1361 // it is very unlikely that the object is being used as a dictionary
1362 // and there is a good chance that allowing more map transitions
1363 // will be worth it.
1364 return Max(map()->inobject_properties(), kMaxFastProperties);
1365}
1366
1367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001369 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001370 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001371 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372 }
1373}
1374
1375
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001376bool Object::ToArrayIndex(uint32_t* index) {
1377 if (IsSmi()) {
1378 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379 if (value < 0) return false;
1380 *index = value;
1381 return true;
1382 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001383 if (IsHeapNumber()) {
1384 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385 uint32_t uint_value = static_cast<uint32_t>(value);
1386 if (value == static_cast<double>(uint_value)) {
1387 *index = uint_value;
1388 return true;
1389 }
1390 }
1391 return false;
1392}
1393
1394
1395bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1396 if (!this->IsJSValue()) return false;
1397
1398 JSValue* js_value = JSValue::cast(this);
1399 if (!js_value->value()->IsString()) return false;
1400
1401 String* str = String::cast(js_value->value());
1402 if (index >= (uint32_t)str->length()) return false;
1403
1404 return true;
1405}
1406
1407
1408Object* FixedArray::get(int index) {
1409 ASSERT(index >= 0 && index < this->length());
1410 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1411}
1412
1413
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001414void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001415 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001416 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1417 int offset = kHeaderSize + index * kPointerSize;
1418 WRITE_FIELD(this, offset, value);
1419}
1420
1421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001423 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001424 ASSERT(index >= 0 && index < this->length());
1425 int offset = kHeaderSize + index * kPointerSize;
1426 WRITE_FIELD(this, offset, value);
1427 WRITE_BARRIER(this, offset);
1428}
1429
1430
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001431WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1433 return UPDATE_WRITE_BARRIER;
1434}
1435
1436
1437void FixedArray::set(int index,
1438 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001439 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001440 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441 ASSERT(index >= 0 && index < this->length());
1442 int offset = kHeaderSize + index * kPointerSize;
1443 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001444 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445}
1446
1447
1448void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001449 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001451 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1453}
1454
1455
1456void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001457 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458 ASSERT(index >= 0 && index < this->length());
1459 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1460 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1461 Heap::undefined_value());
1462}
1463
1464
ager@chromium.org236ad962008-09-25 09:45:57 +00001465void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001466 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001467 ASSERT(index >= 0 && index < this->length());
1468 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1469 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1470}
1471
1472
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001474 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475 ASSERT(index >= 0 && index < this->length());
1476 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1477 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1478}
1479
1480
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001481void FixedArray::set_unchecked(int index, Smi* value) {
1482 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1483 int offset = kHeaderSize + index * kPointerSize;
1484 WRITE_FIELD(this, offset, value);
1485}
1486
1487
1488void FixedArray::set_null_unchecked(int index) {
1489 ASSERT(index >= 0 && index < this->length());
1490 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1491 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1492}
1493
1494
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001495Object** FixedArray::data_start() {
1496 return HeapObject::RawField(this, kHeaderSize);
1497}
1498
1499
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001500bool DescriptorArray::IsEmpty() {
1501 ASSERT(this == Heap::empty_descriptor_array() ||
1502 this->length() > 2);
1503 return this == Heap::empty_descriptor_array();
1504}
1505
1506
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1508 Object* tmp = array->get(first);
1509 fast_set(array, first, array->get(second));
1510 fast_set(array, second, tmp);
1511}
1512
1513
1514int DescriptorArray::Search(String* name) {
1515 SLOW_ASSERT(IsSortedNoDuplicates());
1516
1517 // Check for empty descriptor array.
1518 int nof = number_of_descriptors();
1519 if (nof == 0) return kNotFound;
1520
1521 // Fast case: do linear search for small arrays.
1522 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001523 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001524 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001525 }
1526
1527 // Slow case: perform binary search.
1528 return BinarySearch(name, 0, nof - 1);
1529}
1530
1531
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001532int DescriptorArray::SearchWithCache(String* name) {
1533 int number = DescriptorLookupCache::Lookup(this, name);
1534 if (number == DescriptorLookupCache::kAbsent) {
1535 number = Search(name);
1536 DescriptorLookupCache::Update(this, name, number);
1537 }
1538 return number;
1539}
1540
1541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001542String* DescriptorArray::GetKey(int descriptor_number) {
1543 ASSERT(descriptor_number < number_of_descriptors());
1544 return String::cast(get(ToKeyIndex(descriptor_number)));
1545}
1546
1547
1548Object* DescriptorArray::GetValue(int descriptor_number) {
1549 ASSERT(descriptor_number < number_of_descriptors());
1550 return GetContentArray()->get(ToValueIndex(descriptor_number));
1551}
1552
1553
1554Smi* DescriptorArray::GetDetails(int descriptor_number) {
1555 ASSERT(descriptor_number < number_of_descriptors());
1556 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1557}
1558
1559
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001560PropertyType DescriptorArray::GetType(int descriptor_number) {
1561 ASSERT(descriptor_number < number_of_descriptors());
1562 return PropertyDetails(GetDetails(descriptor_number)).type();
1563}
1564
1565
1566int DescriptorArray::GetFieldIndex(int descriptor_number) {
1567 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1568}
1569
1570
1571JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1572 return JSFunction::cast(GetValue(descriptor_number));
1573}
1574
1575
1576Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1577 ASSERT(GetType(descriptor_number) == CALLBACKS);
1578 return GetValue(descriptor_number);
1579}
1580
1581
1582AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1583 ASSERT(GetType(descriptor_number) == CALLBACKS);
1584 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1585 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1586}
1587
1588
1589bool DescriptorArray::IsProperty(int descriptor_number) {
1590 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1591}
1592
1593
1594bool DescriptorArray::IsTransition(int descriptor_number) {
1595 PropertyType t = GetType(descriptor_number);
1596 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1597}
1598
1599
1600bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1601 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1602}
1603
1604
1605bool DescriptorArray::IsDontEnum(int descriptor_number) {
1606 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1607}
1608
1609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1611 desc->Init(GetKey(descriptor_number),
1612 GetValue(descriptor_number),
1613 GetDetails(descriptor_number));
1614}
1615
1616
1617void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1618 // Range check.
1619 ASSERT(descriptor_number < number_of_descriptors());
1620
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001621 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1623 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1624
1625 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1626 FixedArray* content_array = GetContentArray();
1627 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1628 fast_set(content_array, ToDetailsIndex(descriptor_number),
1629 desc->GetDetails().AsSmi());
1630}
1631
1632
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001633void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1634 Descriptor desc;
1635 src->Get(src_index, &desc);
1636 Set(index, &desc);
1637}
1638
1639
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001640void DescriptorArray::Swap(int first, int second) {
1641 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1642 FixedArray* content_array = GetContentArray();
1643 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1644 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1645}
1646
1647
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001648bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001649 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001650 if (!max_index_object->IsSmi()) return false;
1651 return 0 !=
1652 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1653}
1654
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001655uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001657 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001658 if (!max_index_object->IsSmi()) return 0;
1659 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1660 return value >> kRequiresSlowElementsTagSize;
1661}
1662
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001663void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001664 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001665}
1666
1667
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668// ------------------------------------
1669// Cast operations
1670
1671
1672CAST_ACCESSOR(FixedArray)
1673CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001674CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001675CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001676CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001677CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001678CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001679CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680CAST_ACCESSOR(String)
1681CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001682CAST_ACCESSOR(SeqAsciiString)
1683CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001684CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001685CAST_ACCESSOR(ExternalString)
1686CAST_ACCESSOR(ExternalAsciiString)
1687CAST_ACCESSOR(ExternalTwoByteString)
1688CAST_ACCESSOR(JSObject)
1689CAST_ACCESSOR(Smi)
1690CAST_ACCESSOR(Failure)
1691CAST_ACCESSOR(HeapObject)
1692CAST_ACCESSOR(HeapNumber)
1693CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001694CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695CAST_ACCESSOR(SharedFunctionInfo)
1696CAST_ACCESSOR(Map)
1697CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001698CAST_ACCESSOR(GlobalObject)
1699CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001700CAST_ACCESSOR(JSGlobalObject)
1701CAST_ACCESSOR(JSBuiltinsObject)
1702CAST_ACCESSOR(Code)
1703CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001704CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705CAST_ACCESSOR(Proxy)
1706CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001707CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001708CAST_ACCESSOR(ExternalArray)
1709CAST_ACCESSOR(ExternalByteArray)
1710CAST_ACCESSOR(ExternalUnsignedByteArray)
1711CAST_ACCESSOR(ExternalShortArray)
1712CAST_ACCESSOR(ExternalUnsignedShortArray)
1713CAST_ACCESSOR(ExternalIntArray)
1714CAST_ACCESSOR(ExternalUnsignedIntArray)
1715CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001716CAST_ACCESSOR(Struct)
1717
1718
1719#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1720 STRUCT_LIST(MAKE_STRUCT_CAST)
1721#undef MAKE_STRUCT_CAST
1722
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001723
1724template <typename Shape, typename Key>
1725HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726 ASSERT(obj->IsHashTable());
1727 return reinterpret_cast<HashTable*>(obj);
1728}
1729
1730
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001731SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1732SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1733
1734INT_ACCESSORS(PixelArray, length, kLengthOffset)
1735INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736
1737
ager@chromium.orgac091b72010-05-05 07:34:42 +00001738SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001739
1740
1741uint32_t String::hash_field() {
1742 return READ_UINT32_FIELD(this, kHashFieldOffset);
1743}
1744
1745
1746void String::set_hash_field(uint32_t value) {
1747 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001748#if V8_HOST_ARCH_64_BIT
1749 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1750#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001751}
1752
1753
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754bool String::Equals(String* other) {
1755 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001756 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1757 return false;
1758 }
1759 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760}
1761
1762
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001763Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001764 if (!StringShape(this).IsCons()) return this;
1765 ConsString* cons = ConsString::cast(this);
1766 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001767 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768}
1769
1770
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001771String* String::TryFlattenGetString(PretenureFlag pretenure) {
1772 Object* flat = TryFlatten(pretenure);
1773 return flat->IsFailure() ? this : String::cast(flat);
1774}
1775
1776
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001777uint16_t String::Get(int index) {
1778 ASSERT(index >= 0 && index < length());
1779 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001780 case kSeqStringTag | kAsciiStringTag:
1781 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1782 case kSeqStringTag | kTwoByteStringTag:
1783 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1784 case kConsStringTag | kAsciiStringTag:
1785 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001787 case kExternalStringTag | kAsciiStringTag:
1788 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1789 case kExternalStringTag | kTwoByteStringTag:
1790 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791 default:
1792 break;
1793 }
1794
1795 UNREACHABLE();
1796 return 0;
1797}
1798
1799
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001800void String::Set(int index, uint16_t value) {
1801 ASSERT(index >= 0 && index < length());
1802 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803
ager@chromium.org5ec48922009-05-05 07:25:34 +00001804 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001805 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1806 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001807}
1808
1809
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001810bool String::IsFlat() {
1811 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001812 case kConsStringTag: {
1813 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001814 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001815 return second->length() == 0;
1816 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001817 default:
1818 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001819 }
1820}
1821
1822
ager@chromium.org7c537e22008-10-16 08:43:32 +00001823uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 ASSERT(index >= 0 && index < length());
1825 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1826}
1827
1828
ager@chromium.org7c537e22008-10-16 08:43:32 +00001829void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1831 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1832 static_cast<byte>(value));
1833}
1834
1835
ager@chromium.org7c537e22008-10-16 08:43:32 +00001836Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837 return FIELD_ADDR(this, kHeaderSize);
1838}
1839
1840
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001841char* SeqAsciiString::GetChars() {
1842 return reinterpret_cast<char*>(GetCharsAddress());
1843}
1844
1845
ager@chromium.org7c537e22008-10-16 08:43:32 +00001846Address SeqTwoByteString::GetCharsAddress() {
1847 return FIELD_ADDR(this, kHeaderSize);
1848}
1849
1850
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001851uc16* SeqTwoByteString::GetChars() {
1852 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1853}
1854
1855
ager@chromium.org7c537e22008-10-16 08:43:32 +00001856uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001857 ASSERT(index >= 0 && index < length());
1858 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1859}
1860
1861
ager@chromium.org7c537e22008-10-16 08:43:32 +00001862void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863 ASSERT(index >= 0 && index < length());
1864 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1865}
1866
1867
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001868int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001869 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870}
1871
1872
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001873int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001874 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875}
1876
1877
ager@chromium.org870a0b62008-11-04 11:43:05 +00001878String* ConsString::first() {
1879 return String::cast(READ_FIELD(this, kFirstOffset));
1880}
1881
1882
1883Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884 return READ_FIELD(this, kFirstOffset);
1885}
1886
1887
ager@chromium.org870a0b62008-11-04 11:43:05 +00001888void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001889 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001890 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891}
1892
1893
ager@chromium.org870a0b62008-11-04 11:43:05 +00001894String* ConsString::second() {
1895 return String::cast(READ_FIELD(this, kSecondOffset));
1896}
1897
1898
1899Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001900 return READ_FIELD(this, kSecondOffset);
1901}
1902
1903
ager@chromium.org870a0b62008-11-04 11:43:05 +00001904void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001906 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001907}
1908
1909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001910ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1911 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1912}
1913
1914
1915void ExternalAsciiString::set_resource(
1916 ExternalAsciiString::Resource* resource) {
1917 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1918}
1919
1920
1921ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1922 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1923}
1924
1925
1926void ExternalTwoByteString::set_resource(
1927 ExternalTwoByteString::Resource* resource) {
1928 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1929}
1930
1931
ager@chromium.orgac091b72010-05-05 07:34:42 +00001932void JSFunctionResultCache::MakeZeroSize() {
1933 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1934 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1935}
1936
1937
1938void JSFunctionResultCache::Clear() {
1939 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1940 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1941 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1942 MakeZeroSize();
1943}
1944
1945
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946byte ByteArray::get(int index) {
1947 ASSERT(index >= 0 && index < this->length());
1948 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1949}
1950
1951
1952void ByteArray::set(int index, byte value) {
1953 ASSERT(index >= 0 && index < this->length());
1954 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1955}
1956
1957
1958int ByteArray::get_int(int index) {
1959 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1960 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1961}
1962
1963
1964ByteArray* ByteArray::FromDataStartAddress(Address address) {
1965 ASSERT_TAG_ALIGNED(address);
1966 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1967}
1968
1969
1970Address ByteArray::GetDataStartAddress() {
1971 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1972}
1973
1974
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001975uint8_t* PixelArray::external_pointer() {
1976 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1977 return reinterpret_cast<uint8_t*>(ptr);
1978}
1979
1980
1981void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1982 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1983 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1984}
1985
1986
1987uint8_t PixelArray::get(int index) {
1988 ASSERT((index >= 0) && (index < this->length()));
1989 uint8_t* ptr = external_pointer();
1990 return ptr[index];
1991}
1992
1993
1994void PixelArray::set(int index, uint8_t value) {
1995 ASSERT((index >= 0) && (index < this->length()));
1996 uint8_t* ptr = external_pointer();
1997 ptr[index] = value;
1998}
1999
2000
ager@chromium.org3811b432009-10-28 14:53:37 +00002001void* ExternalArray::external_pointer() {
2002 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2003 return reinterpret_cast<void*>(ptr);
2004}
2005
2006
2007void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2008 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2009 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2010}
2011
2012
2013int8_t ExternalByteArray::get(int index) {
2014 ASSERT((index >= 0) && (index < this->length()));
2015 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2016 return ptr[index];
2017}
2018
2019
2020void ExternalByteArray::set(int index, int8_t value) {
2021 ASSERT((index >= 0) && (index < this->length()));
2022 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2023 ptr[index] = value;
2024}
2025
2026
2027uint8_t ExternalUnsignedByteArray::get(int index) {
2028 ASSERT((index >= 0) && (index < this->length()));
2029 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2030 return ptr[index];
2031}
2032
2033
2034void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2035 ASSERT((index >= 0) && (index < this->length()));
2036 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2037 ptr[index] = value;
2038}
2039
2040
2041int16_t ExternalShortArray::get(int index) {
2042 ASSERT((index >= 0) && (index < this->length()));
2043 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2044 return ptr[index];
2045}
2046
2047
2048void ExternalShortArray::set(int index, int16_t value) {
2049 ASSERT((index >= 0) && (index < this->length()));
2050 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2051 ptr[index] = value;
2052}
2053
2054
2055uint16_t ExternalUnsignedShortArray::get(int index) {
2056 ASSERT((index >= 0) && (index < this->length()));
2057 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2058 return ptr[index];
2059}
2060
2061
2062void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2063 ASSERT((index >= 0) && (index < this->length()));
2064 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2065 ptr[index] = value;
2066}
2067
2068
2069int32_t ExternalIntArray::get(int index) {
2070 ASSERT((index >= 0) && (index < this->length()));
2071 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2072 return ptr[index];
2073}
2074
2075
2076void ExternalIntArray::set(int index, int32_t value) {
2077 ASSERT((index >= 0) && (index < this->length()));
2078 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2079 ptr[index] = value;
2080}
2081
2082
2083uint32_t ExternalUnsignedIntArray::get(int index) {
2084 ASSERT((index >= 0) && (index < this->length()));
2085 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2086 return ptr[index];
2087}
2088
2089
2090void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2091 ASSERT((index >= 0) && (index < this->length()));
2092 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2093 ptr[index] = value;
2094}
2095
2096
2097float ExternalFloatArray::get(int index) {
2098 ASSERT((index >= 0) && (index < this->length()));
2099 float* ptr = static_cast<float*>(external_pointer());
2100 return ptr[index];
2101}
2102
2103
2104void ExternalFloatArray::set(int index, float value) {
2105 ASSERT((index >= 0) && (index < this->length()));
2106 float* ptr = static_cast<float*>(external_pointer());
2107 ptr[index] = value;
2108}
2109
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002110
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002111int Map::visitor_id() {
2112 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2113}
2114
2115
2116void Map::set_visitor_id(int id) {
2117 ASSERT(0 <= id && id < 256);
2118 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2119}
2120
ager@chromium.org3811b432009-10-28 14:53:37 +00002121
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002123 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2124}
2125
2126
2127int Map::inobject_properties() {
2128 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129}
2130
2131
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002132int Map::pre_allocated_property_fields() {
2133 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2134}
2135
2136
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002138 int instance_size = map->instance_size();
2139 if (instance_size != kVariableSizeSentinel) return instance_size;
2140 // We can ignore the "symbol" bit becase it is only set for symbols
2141 // and implies a string type.
2142 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002143 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002145 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002147 if (instance_type == ASCII_STRING_TYPE) {
2148 return SeqAsciiString::SizeFor(
2149 reinterpret_cast<SeqAsciiString*>(this)->length());
2150 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002151 if (instance_type == BYTE_ARRAY_TYPE) {
2152 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2153 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002154 if (instance_type == STRING_TYPE) {
2155 return SeqTwoByteString::SizeFor(
2156 reinterpret_cast<SeqTwoByteString*>(this)->length());
2157 }
2158 ASSERT(instance_type == CODE_TYPE);
2159 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160}
2161
2162
2163void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002164 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002165 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166 ASSERT(0 <= value && value < 256);
2167 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2168}
2169
2170
ager@chromium.org7c537e22008-10-16 08:43:32 +00002171void Map::set_inobject_properties(int value) {
2172 ASSERT(0 <= value && value < 256);
2173 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2174}
2175
2176
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002177void Map::set_pre_allocated_property_fields(int value) {
2178 ASSERT(0 <= value && value < 256);
2179 WRITE_BYTE_FIELD(this,
2180 kPreAllocatedPropertyFieldsOffset,
2181 static_cast<byte>(value));
2182}
2183
2184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185InstanceType Map::instance_type() {
2186 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2187}
2188
2189
2190void Map::set_instance_type(InstanceType value) {
2191 ASSERT(0 <= value && value < 256);
2192 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2193}
2194
2195
2196int Map::unused_property_fields() {
2197 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2198}
2199
2200
2201void Map::set_unused_property_fields(int value) {
2202 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2203}
2204
2205
2206byte Map::bit_field() {
2207 return READ_BYTE_FIELD(this, kBitFieldOffset);
2208}
2209
2210
2211void Map::set_bit_field(byte value) {
2212 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2213}
2214
2215
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002216byte Map::bit_field2() {
2217 return READ_BYTE_FIELD(this, kBitField2Offset);
2218}
2219
2220
2221void Map::set_bit_field2(byte value) {
2222 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2223}
2224
2225
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226void Map::set_non_instance_prototype(bool value) {
2227 if (value) {
2228 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2229 } else {
2230 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2231 }
2232}
2233
2234
2235bool Map::has_non_instance_prototype() {
2236 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2237}
2238
2239
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002240void Map::set_function_with_prototype(bool value) {
2241 if (value) {
2242 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2243 } else {
2244 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2245 }
2246}
2247
2248
2249bool Map::function_with_prototype() {
2250 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2251}
2252
2253
ager@chromium.org870a0b62008-11-04 11:43:05 +00002254void Map::set_is_access_check_needed(bool access_check_needed) {
2255 if (access_check_needed) {
2256 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2257 } else {
2258 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2259 }
2260}
2261
2262
2263bool Map::is_access_check_needed() {
2264 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2265}
2266
2267
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002268void Map::set_is_extensible(bool value) {
2269 if (value) {
2270 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2271 } else {
2272 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2273 }
2274}
2275
2276bool Map::is_extensible() {
2277 return ((1 << kIsExtensible) & bit_field2()) != 0;
2278}
2279
2280
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002281void Map::set_attached_to_shared_function_info(bool value) {
2282 if (value) {
2283 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2284 } else {
2285 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2286 }
2287}
2288
2289bool Map::attached_to_shared_function_info() {
2290 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2291}
2292
2293
2294void Map::set_is_shared(bool value) {
2295 if (value) {
2296 set_bit_field2(bit_field2() | (1 << kIsShared));
2297 } else {
2298 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2299 }
2300}
2301
2302bool Map::is_shared() {
2303 return ((1 << kIsShared) & bit_field2()) != 0;
2304}
2305
2306
2307JSFunction* Map::unchecked_constructor() {
2308 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2309}
2310
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312Code::Flags Code::flags() {
2313 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2314}
2315
2316
2317void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002318 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002320 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2321 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002322 ExtractArgumentsCountFromFlags(flags) >= 0);
2323 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2324}
2325
2326
2327Code::Kind Code::kind() {
2328 return ExtractKindFromFlags(flags());
2329}
2330
2331
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002332InLoopFlag Code::ic_in_loop() {
2333 return ExtractICInLoopFromFlags(flags());
2334}
2335
2336
kasper.lund7276f142008-07-30 08:49:36 +00002337InlineCacheState Code::ic_state() {
2338 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339 // Only allow uninitialized or debugger states for non-IC code
2340 // objects. This is used in the debugger to determine whether or not
2341 // a call to code object has been replaced with a debug break call.
2342 ASSERT(is_inline_cache_stub() ||
2343 result == UNINITIALIZED ||
2344 result == DEBUG_BREAK ||
2345 result == DEBUG_PREPARE_STEP_IN);
2346 return result;
2347}
2348
2349
2350PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002351 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002352 return ExtractTypeFromFlags(flags());
2353}
2354
2355
2356int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002357 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358 return ExtractArgumentsCountFromFlags(flags());
2359}
2360
2361
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002362int Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002363 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002364 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002365}
2366
2367
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002368void Code::set_major_key(int major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002369 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002370 ASSERT(0 <= major && major < 256);
2371 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372}
2373
2374
2375bool Code::is_inline_cache_stub() {
2376 Kind kind = this->kind();
2377 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2378}
2379
2380
2381Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002382 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002383 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002385 int argc,
2386 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387 // Compute the bit mask.
2388 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002389 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002390 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 bits |= type << kFlagsTypeShift;
2392 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002393 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394 // Cast to flags and validate result before returning it.
2395 Flags result = static_cast<Flags>(bits);
2396 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002397 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002398 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399 ASSERT(ExtractTypeFromFlags(result) == type);
2400 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2401 return result;
2402}
2403
2404
2405Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2406 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002407 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002408 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002410 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411}
2412
2413
2414Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2415 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2416 return static_cast<Kind>(bits);
2417}
2418
2419
kasper.lund7276f142008-07-30 08:49:36 +00002420InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2421 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002422 return static_cast<InlineCacheState>(bits);
2423}
2424
2425
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002426InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2427 int bits = (flags & kFlagsICInLoopMask);
2428 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2429}
2430
2431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2433 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2434 return static_cast<PropertyType>(bits);
2435}
2436
2437
2438int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2439 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2440}
2441
2442
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002443InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2444 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2445 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2446}
2447
2448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002449Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2450 int bits = flags & ~kFlagsTypeMask;
2451 return static_cast<Flags>(bits);
2452}
2453
2454
ager@chromium.org8bb60582008-12-11 12:02:20 +00002455Code* Code::GetCodeFromTargetAddress(Address address) {
2456 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2457 // GetCodeFromTargetAddress might be called when marking objects during mark
2458 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2459 // Code::cast. Code::cast does not work when the object's map is
2460 // marked.
2461 Code* result = reinterpret_cast<Code*>(code);
2462 return result;
2463}
2464
2465
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002466Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2467 return HeapObject::
2468 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2469}
2470
2471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002472Object* Map::prototype() {
2473 return READ_FIELD(this, kPrototypeOffset);
2474}
2475
2476
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002477void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002478 ASSERT(value->IsNull() || value->IsJSObject());
2479 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002480 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481}
2482
2483
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002484Object* Map::GetFastElementsMap() {
2485 if (has_fast_elements()) return this;
2486 Object* obj = CopyDropTransitions();
2487 if (obj->IsFailure()) return obj;
2488 Map* new_map = Map::cast(obj);
2489 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002490 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002491 return new_map;
2492}
2493
2494
2495Object* Map::GetSlowElementsMap() {
2496 if (!has_fast_elements()) return this;
2497 Object* obj = CopyDropTransitions();
2498 if (obj->IsFailure()) return obj;
2499 Map* new_map = Map::cast(obj);
2500 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002501 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002502 return new_map;
2503}
2504
2505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002506ACCESSORS(Map, instance_descriptors, DescriptorArray,
2507 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002508ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002509ACCESSORS(Map, constructor, Object, kConstructorOffset)
2510
2511ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2512ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2513
2514ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2515ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002516ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002518ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002519
2520ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2521ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2522ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2523ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2524ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002525ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002526
2527ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2528ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2529ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2530
2531ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2532ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2533ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2534ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2535ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2536ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2537
2538ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2539ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2540
2541ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2542ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2543
2544ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2545ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2547 kPropertyAccessorsOffset)
2548ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2549 kPrototypeTemplateOffset)
2550ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2551ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2552 kNamedPropertyHandlerOffset)
2553ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2554 kIndexedPropertyHandlerOffset)
2555ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2556 kInstanceTemplateOffset)
2557ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2558ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002559ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2560 kInstanceCallHandlerOffset)
2561ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2562 kAccessCheckInfoOffset)
2563ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2564
2565ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002566ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2567 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002568
2569ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2570ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2571
2572ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2573
2574ACCESSORS(Script, source, Object, kSourceOffset)
2575ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002576ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002577ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2578ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002579ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002580ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002581ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2582ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002583ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002584ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002585ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002586ACCESSORS(Script, eval_from_instructions_offset, Smi,
2587 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002588
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002589#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2591ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2592ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2593ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2594
2595ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2596ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2597ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2598ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002599#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600
2601ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002602ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002603ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002604ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2605 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002606ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002607ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2608ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002609ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002610ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2611 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612
2613BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2614 kHiddenPrototypeBit)
2615BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2616BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2617 kNeedsAccessCheckBit)
2618BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2619 kIsExpressionBit)
2620BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2621 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002622BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002623 has_only_simple_this_property_assignments,
2624 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002625BOOL_ACCESSORS(SharedFunctionInfo,
2626 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002627 try_full_codegen,
2628 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002629BOOL_ACCESSORS(SharedFunctionInfo,
2630 compiler_hints,
2631 allows_lazy_compilation,
2632 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002634
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002635#if V8_HOST_ARCH_32_BIT
2636SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2637SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002638 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002639SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002640 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002641SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2642SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002643 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002644SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2645SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002646 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002647SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002648 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002649SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002650 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002651#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002652
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002653#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2654 int holder::name() { \
2655 int value = READ_INT_FIELD(this, offset); \
2656 ASSERT(kHeapObjectTag == 1); \
2657 ASSERT((value & kHeapObjectTag) == 0); \
2658 return value >> 1; \
2659 } \
2660 void holder::set_##name(int value) { \
2661 ASSERT(kHeapObjectTag == 1); \
2662 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2663 (value & 0xC0000000) == 0x000000000); \
2664 WRITE_INT_FIELD(this, \
2665 offset, \
2666 (value << 1) & ~kHeapObjectTag); \
2667 }
2668
2669#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2670 INT_ACCESSORS(holder, name, offset)
2671
2672
2673
2674PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2675PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2676 kFormalParameterCountOffset)
2677
2678PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2679 kExpectedNofPropertiesOffset)
2680PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2681
2682PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2683 kStartPositionAndTypeOffset)
2684PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2685
2686PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2687 kFunctionTokenPositionOffset)
2688PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2689 kCompilerHintsOffset)
2690
2691PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2692 kThisPropertyAssignmentsCountOffset)
2693#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002694
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002695
2696int SharedFunctionInfo::construction_count() {
2697 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2698}
2699
2700
2701void SharedFunctionInfo::set_construction_count(int value) {
2702 ASSERT(0 <= value && value < 256);
2703 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2704}
2705
2706
2707bool SharedFunctionInfo::live_objects_may_exist() {
2708 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2709}
2710
2711
2712void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2713 if (value) {
2714 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2715 } else {
2716 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2717 }
2718}
2719
2720
2721bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2722 return initial_map() != Heap::undefined_value();
2723}
2724
2725
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002726ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2727ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2728
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002729bool Script::HasValidSource() {
2730 Object* src = this->source();
2731 if (!src->IsString()) return true;
2732 String* src_str = String::cast(src);
2733 if (!StringShape(src_str).IsExternal()) return true;
2734 if (src_str->IsAsciiRepresentation()) {
2735 return ExternalAsciiString::cast(src)->resource() != NULL;
2736 } else if (src_str->IsTwoByteRepresentation()) {
2737 return ExternalTwoByteString::cast(src)->resource() != NULL;
2738 }
2739 return true;
2740}
2741
2742
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002743void SharedFunctionInfo::DontAdaptArguments() {
2744 ASSERT(code()->kind() == Code::BUILTIN);
2745 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2746}
2747
2748
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002749int SharedFunctionInfo::start_position() {
2750 return start_position_and_type() >> kStartPositionShift;
2751}
2752
2753
2754void SharedFunctionInfo::set_start_position(int start_position) {
2755 set_start_position_and_type((start_position << kStartPositionShift)
2756 | (start_position_and_type() & ~kStartPositionMask));
2757}
2758
2759
2760Code* SharedFunctionInfo::code() {
2761 return Code::cast(READ_FIELD(this, kCodeOffset));
2762}
2763
2764
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002765Code* SharedFunctionInfo::unchecked_code() {
2766 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2767}
2768
2769
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002770void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002772 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002773}
2774
2775
ager@chromium.orgb5737492010-07-15 09:29:43 +00002776SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2777 return reinterpret_cast<SerializedScopeInfo*>(
2778 READ_FIELD(this, kScopeInfoOffset));
2779}
2780
2781
2782void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2783 WriteBarrierMode mode) {
2784 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2785 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2786}
2787
2788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002790 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791}
2792
2793
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002794bool SharedFunctionInfo::IsApiFunction() {
2795 return function_data()->IsFunctionTemplateInfo();
2796}
2797
2798
2799FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2800 ASSERT(IsApiFunction());
2801 return FunctionTemplateInfo::cast(function_data());
2802}
2803
2804
2805bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002806 return function_data()->IsSmi();
2807}
2808
2809
2810int SharedFunctionInfo::custom_call_generator_id() {
2811 ASSERT(HasCustomCallGenerator());
2812 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002813}
2814
2815
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002816int SharedFunctionInfo::code_age() {
2817 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2818}
2819
2820
2821void SharedFunctionInfo::set_code_age(int code_age) {
2822 set_compiler_hints(compiler_hints() |
2823 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2824}
2825
2826
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002827bool JSFunction::IsBuiltin() {
2828 return context()->global()->IsJSBuiltinsObject();
2829}
2830
2831
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002833 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834}
2835
2836
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002837Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002838 return reinterpret_cast<Code*>(
2839 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002840}
2841
2842
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002844 // Skip the write barrier because code is never in new space.
2845 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002846 Address entry = value->entry();
2847 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848}
2849
2850
2851Context* JSFunction::context() {
2852 return Context::cast(READ_FIELD(this, kContextOffset));
2853}
2854
2855
2856Object* JSFunction::unchecked_context() {
2857 return READ_FIELD(this, kContextOffset);
2858}
2859
2860
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002861SharedFunctionInfo* JSFunction::unchecked_shared() {
2862 return reinterpret_cast<SharedFunctionInfo*>(
2863 READ_FIELD(this, kSharedFunctionInfoOffset));
2864}
2865
2866
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002867void JSFunction::set_context(Object* value) {
2868 ASSERT(value == Heap::undefined_value() || value->IsContext());
2869 WRITE_FIELD(this, kContextOffset, value);
2870 WRITE_BARRIER(this, kContextOffset);
2871}
2872
2873ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2874 kPrototypeOrInitialMapOffset)
2875
2876
2877Map* JSFunction::initial_map() {
2878 return Map::cast(prototype_or_initial_map());
2879}
2880
2881
2882void JSFunction::set_initial_map(Map* value) {
2883 set_prototype_or_initial_map(value);
2884}
2885
2886
2887bool JSFunction::has_initial_map() {
2888 return prototype_or_initial_map()->IsMap();
2889}
2890
2891
2892bool JSFunction::has_instance_prototype() {
2893 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2894}
2895
2896
2897bool JSFunction::has_prototype() {
2898 return map()->has_non_instance_prototype() || has_instance_prototype();
2899}
2900
2901
2902Object* JSFunction::instance_prototype() {
2903 ASSERT(has_instance_prototype());
2904 if (has_initial_map()) return initial_map()->prototype();
2905 // When there is no initial map and the prototype is a JSObject, the
2906 // initial map field is used for the prototype field.
2907 return prototype_or_initial_map();
2908}
2909
2910
2911Object* JSFunction::prototype() {
2912 ASSERT(has_prototype());
2913 // If the function's prototype property has been set to a non-JSObject
2914 // value, that value is stored in the constructor field of the map.
2915 if (map()->has_non_instance_prototype()) return map()->constructor();
2916 return instance_prototype();
2917}
2918
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002919bool JSFunction::should_have_prototype() {
2920 return map()->function_with_prototype();
2921}
2922
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002923
2924bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002925 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926}
2927
2928
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002929int JSFunction::NumberOfLiterals() {
2930 return literals()->length();
2931}
2932
2933
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2935 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002936 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002937}
2938
2939
2940void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2941 Object* value) {
2942 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002943 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2944 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2945}
2946
2947
2948Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2949 ASSERT(0 <= id && id < kJSBuiltinsCount);
2950 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2951}
2952
2953
2954void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2955 Code* value) {
2956 ASSERT(0 <= id && id < kJSBuiltinsCount);
2957 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2958 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002959}
2960
2961
2962Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002963 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964}
2965
2966
2967void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002968 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002969}
2970
2971
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002972ACCESSORS(JSValue, value, Object, kValueOffset)
2973
2974
2975JSValue* JSValue::cast(Object* obj) {
2976 ASSERT(obj->IsJSValue());
2977 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2978 return reinterpret_cast<JSValue*>(obj);
2979}
2980
2981
2982INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002983ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984
2985
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986byte* Code::instruction_start() {
2987 return FIELD_ADDR(this, kHeaderSize);
2988}
2989
2990
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002991byte* Code::instruction_end() {
2992 return instruction_start() + instruction_size();
2993}
2994
2995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002996int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002997 return RoundUp(instruction_size(), kObjectAlignment);
2998}
2999
3000
3001ByteArray* Code::unchecked_relocation_info() {
3002 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003003}
3004
3005
3006byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003007 return unchecked_relocation_info()->GetDataStartAddress();
3008}
3009
3010
3011int Code::relocation_size() {
3012 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003013}
3014
3015
3016byte* Code::entry() {
3017 return instruction_start();
3018}
3019
3020
3021bool Code::contains(byte* pc) {
3022 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003023 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003024}
3025
3026
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003027ACCESSORS(JSArray, length, Object, kLengthOffset)
3028
3029
ager@chromium.org236ad962008-09-25 09:45:57 +00003030ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003031
3032
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003033JSRegExp::Type JSRegExp::TypeTag() {
3034 Object* data = this->data();
3035 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3036 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3037 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003038}
3039
3040
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003041int JSRegExp::CaptureCount() {
3042 switch (TypeTag()) {
3043 case ATOM:
3044 return 0;
3045 case IRREGEXP:
3046 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3047 default:
3048 UNREACHABLE();
3049 return -1;
3050 }
3051}
3052
3053
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003054JSRegExp::Flags JSRegExp::GetFlags() {
3055 ASSERT(this->data()->IsFixedArray());
3056 Object* data = this->data();
3057 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3058 return Flags(smi->value());
3059}
3060
3061
3062String* JSRegExp::Pattern() {
3063 ASSERT(this->data()->IsFixedArray());
3064 Object* data = this->data();
3065 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3066 return pattern;
3067}
3068
3069
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003070Object* JSRegExp::DataAt(int index) {
3071 ASSERT(TypeTag() != NOT_COMPILED);
3072 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003073}
3074
3075
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003076void JSRegExp::SetDataAt(int index, Object* value) {
3077 ASSERT(TypeTag() != NOT_COMPILED);
3078 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3079 FixedArray::cast(data())->set(index, value);
3080}
3081
3082
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003083JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003084 if (map()->has_fast_elements()) {
3085 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3086 elements()->map() == Heap::fixed_cow_array_map());
3087 return FAST_ELEMENTS;
3088 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003089 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003090 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003091 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3092 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003093 ASSERT(array->IsDictionary());
3094 return DICTIONARY_ELEMENTS;
3095 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003096 if (array->IsExternalArray()) {
3097 switch (array->map()->instance_type()) {
3098 case EXTERNAL_BYTE_ARRAY_TYPE:
3099 return EXTERNAL_BYTE_ELEMENTS;
3100 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3101 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3102 case EXTERNAL_SHORT_ARRAY_TYPE:
3103 return EXTERNAL_SHORT_ELEMENTS;
3104 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3105 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3106 case EXTERNAL_INT_ARRAY_TYPE:
3107 return EXTERNAL_INT_ELEMENTS;
3108 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3109 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3110 default:
3111 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3112 return EXTERNAL_FLOAT_ELEMENTS;
3113 }
3114 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003115 ASSERT(array->IsPixelArray());
3116 return PIXEL_ELEMENTS;
3117}
3118
3119
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003120bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003121 return GetElementsKind() == FAST_ELEMENTS;
3122}
3123
3124
3125bool JSObject::HasDictionaryElements() {
3126 return GetElementsKind() == DICTIONARY_ELEMENTS;
3127}
3128
3129
3130bool JSObject::HasPixelElements() {
3131 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003132}
3133
3134
ager@chromium.org3811b432009-10-28 14:53:37 +00003135bool JSObject::HasExternalArrayElements() {
3136 return (HasExternalByteElements() ||
3137 HasExternalUnsignedByteElements() ||
3138 HasExternalShortElements() ||
3139 HasExternalUnsignedShortElements() ||
3140 HasExternalIntElements() ||
3141 HasExternalUnsignedIntElements() ||
3142 HasExternalFloatElements());
3143}
3144
3145
3146bool JSObject::HasExternalByteElements() {
3147 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3148}
3149
3150
3151bool JSObject::HasExternalUnsignedByteElements() {
3152 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3153}
3154
3155
3156bool JSObject::HasExternalShortElements() {
3157 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3158}
3159
3160
3161bool JSObject::HasExternalUnsignedShortElements() {
3162 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3163}
3164
3165
3166bool JSObject::HasExternalIntElements() {
3167 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3168}
3169
3170
3171bool JSObject::HasExternalUnsignedIntElements() {
3172 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3173}
3174
3175
3176bool JSObject::HasExternalFloatElements() {
3177 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3178}
3179
3180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003181bool JSObject::HasNamedInterceptor() {
3182 return map()->has_named_interceptor();
3183}
3184
3185
3186bool JSObject::HasIndexedInterceptor() {
3187 return map()->has_indexed_interceptor();
3188}
3189
3190
ager@chromium.org5c838252010-02-19 08:53:10 +00003191bool JSObject::AllowsSetElementsLength() {
3192 bool result = elements()->IsFixedArray();
3193 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3194 return result;
3195}
3196
3197
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003198Object* JSObject::EnsureWritableFastElements() {
3199 ASSERT(HasFastElements());
3200 FixedArray* elems = FixedArray::cast(elements());
3201 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003202 Object* writable_elems = Heap::CopyFixedArrayWithMap(elems,
3203 Heap::fixed_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003204 if (writable_elems->IsFailure()) return writable_elems;
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003205 set_elements(FixedArray::cast(writable_elems));
3206 Counters::cow_arrays_converted.Increment();
3207 return writable_elems;
3208}
3209
3210
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003211StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003212 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003213 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003214}
3215
3216
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003217NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003218 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003219 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003220}
3221
3222
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003223bool String::IsHashFieldComputed(uint32_t field) {
3224 return (field & kHashNotComputedMask) == 0;
3225}
3226
3227
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003228bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003229 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003230}
3231
3232
3233uint32_t String::Hash() {
3234 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003235 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003236 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003237 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238 return ComputeAndSetHash();
3239}
3240
3241
ager@chromium.org7c537e22008-10-16 08:43:32 +00003242StringHasher::StringHasher(int length)
3243 : length_(length),
3244 raw_running_hash_(0),
3245 array_index_(0),
3246 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3247 is_first_char_(true),
3248 is_valid_(true) { }
3249
3250
3251bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003252 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003253}
3254
3255
3256void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003257 // Use the Jenkins one-at-a-time hash function to update the hash
3258 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003259 raw_running_hash_ += c;
3260 raw_running_hash_ += (raw_running_hash_ << 10);
3261 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003262 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003263 if (is_array_index_) {
3264 if (c < '0' || c > '9') {
3265 is_array_index_ = false;
3266 } else {
3267 int d = c - '0';
3268 if (is_first_char_) {
3269 is_first_char_ = false;
3270 if (c == '0' && length_ > 1) {
3271 is_array_index_ = false;
3272 return;
3273 }
3274 }
3275 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3276 is_array_index_ = false;
3277 } else {
3278 array_index_ = array_index_ * 10 + d;
3279 }
3280 }
3281 }
3282}
3283
3284
3285void StringHasher::AddCharacterNoIndex(uc32 c) {
3286 ASSERT(!is_array_index());
3287 raw_running_hash_ += c;
3288 raw_running_hash_ += (raw_running_hash_ << 10);
3289 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3290}
3291
3292
3293uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003294 // Get the calculated raw hash value and do some more bit ops to distribute
3295 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003296 uint32_t result = raw_running_hash_;
3297 result += (result << 3);
3298 result ^= (result >> 11);
3299 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003300 if (result == 0) {
3301 result = 27;
3302 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003303 return result;
3304}
3305
3306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003308 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003309 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3310 return false;
3311 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312 return SlowAsArrayIndex(index);
3313}
3314
3315
3316Object* JSObject::GetPrototype() {
3317 return JSObject::cast(this)->map()->prototype();
3318}
3319
3320
3321PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3322 return GetPropertyAttributeWithReceiver(this, key);
3323}
3324
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003325// TODO(504): this may be useful in other places too where JSGlobalProxy
3326// is used.
3327Object* JSObject::BypassGlobalProxy() {
3328 if (IsJSGlobalProxy()) {
3329 Object* proto = GetPrototype();
3330 if (proto->IsNull()) return Heap::undefined_value();
3331 ASSERT(proto->IsJSGlobalObject());
3332 return proto;
3333 }
3334 return this;
3335}
3336
3337
3338bool JSObject::HasHiddenPropertiesObject() {
3339 ASSERT(!IsJSGlobalProxy());
3340 return GetPropertyAttributePostInterceptor(this,
3341 Heap::hidden_symbol(),
3342 false) != ABSENT;
3343}
3344
3345
3346Object* JSObject::GetHiddenPropertiesObject() {
3347 ASSERT(!IsJSGlobalProxy());
3348 PropertyAttributes attributes;
3349 return GetLocalPropertyPostInterceptor(this,
3350 Heap::hidden_symbol(),
3351 &attributes);
3352}
3353
3354
3355Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3356 ASSERT(!IsJSGlobalProxy());
3357 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3358 hidden_obj,
3359 DONT_ENUM);
3360}
3361
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003362
3363bool JSObject::HasElement(uint32_t index) {
3364 return HasElementWithReceiver(this, index);
3365}
3366
3367
3368bool AccessorInfo::all_can_read() {
3369 return BooleanBit::get(flag(), kAllCanReadBit);
3370}
3371
3372
3373void AccessorInfo::set_all_can_read(bool value) {
3374 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3375}
3376
3377
3378bool AccessorInfo::all_can_write() {
3379 return BooleanBit::get(flag(), kAllCanWriteBit);
3380}
3381
3382
3383void AccessorInfo::set_all_can_write(bool value) {
3384 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3385}
3386
3387
ager@chromium.org870a0b62008-11-04 11:43:05 +00003388bool AccessorInfo::prohibits_overwriting() {
3389 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3390}
3391
3392
3393void AccessorInfo::set_prohibits_overwriting(bool value) {
3394 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3395}
3396
3397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003398PropertyAttributes AccessorInfo::property_attributes() {
3399 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3400}
3401
3402
3403void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3404 ASSERT(AttributesField::is_valid(attributes));
3405 int rest_value = flag()->value() & ~AttributesField::mask();
3406 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3407}
3408
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003409template<typename Shape, typename Key>
3410void Dictionary<Shape, Key>::SetEntry(int entry,
3411 Object* key,
3412 Object* value,
3413 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003414 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003415 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003416 AssertNoAllocation no_gc;
3417 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003418 FixedArray::set(index, key, mode);
3419 FixedArray::set(index+1, value, mode);
3420 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003421}
3422
3423
3424void Map::ClearCodeCache() {
3425 // No write barrier is needed since empty_fixed_array is not in new space.
3426 // Please note this function is used during marking:
3427 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003428 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3429 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003430}
3431
3432
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003433void JSArray::EnsureSize(int required_size) {
3434 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003435 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003436 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3437 if (elts->length() < required_size) {
3438 // Doubling in size would be overkill, but leave some slack to avoid
3439 // constantly growing.
3440 Expand(required_size + (required_size >> 3));
3441 // It's a performance benefit to keep a frequently used array in new-space.
3442 } else if (!Heap::new_space()->Contains(elts) &&
3443 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3444 // Expand will allocate a new backing store in new space even if the size
3445 // we asked for isn't larger than what we had before.
3446 Expand(required_size);
3447 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003448}
3449
3450
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003451void JSArray::set_length(Smi* length) {
3452 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3453}
3454
3455
ager@chromium.org7c537e22008-10-16 08:43:32 +00003456void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003457 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003458 set_elements(storage);
3459}
3460
3461
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003462Object* FixedArray::Copy() {
3463 if (length() == 0) return this;
3464 return Heap::CopyFixedArray(this);
3465}
3466
3467
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003468int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3469 return map->instance_size();
3470}
3471
3472
3473void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3474 v->VisitExternalReference(
3475 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3476}
3477
3478
3479template<typename StaticVisitor>
3480void Proxy::ProxyIterateBody() {
3481 StaticVisitor::VisitExternalReference(
3482 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3483}
3484
3485
3486void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3487 typedef v8::String::ExternalAsciiStringResource Resource;
3488 v->VisitExternalAsciiString(
3489 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3490}
3491
3492
3493template<typename StaticVisitor>
3494void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3495 typedef v8::String::ExternalAsciiStringResource Resource;
3496 StaticVisitor::VisitExternalAsciiString(
3497 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3498}
3499
3500
3501void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3502 typedef v8::String::ExternalStringResource Resource;
3503 v->VisitExternalTwoByteString(
3504 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3505}
3506
3507
3508template<typename StaticVisitor>
3509void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3510 typedef v8::String::ExternalStringResource Resource;
3511 StaticVisitor::VisitExternalTwoByteString(
3512 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3513}
3514
3515#define SLOT_ADDR(obj, offset) \
3516 reinterpret_cast<Object**>((obj)->address() + offset)
3517
3518template<int start_offset, int end_offset, int size>
3519void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3520 HeapObject* obj,
3521 ObjectVisitor* v) {
3522 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3523}
3524
3525
3526template<int start_offset>
3527void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3528 int object_size,
3529 ObjectVisitor* v) {
3530 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3531}
3532
3533#undef SLOT_ADDR
3534
3535
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003536#undef CAST_ACCESSOR
3537#undef INT_ACCESSORS
3538#undef SMI_ACCESSORS
3539#undef ACCESSORS
3540#undef FIELD_ADDR
3541#undef READ_FIELD
3542#undef WRITE_FIELD
3543#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003544#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545#undef READ_MEMADDR_FIELD
3546#undef WRITE_MEMADDR_FIELD
3547#undef READ_DOUBLE_FIELD
3548#undef WRITE_DOUBLE_FIELD
3549#undef READ_INT_FIELD
3550#undef WRITE_INT_FIELD
3551#undef READ_SHORT_FIELD
3552#undef WRITE_SHORT_FIELD
3553#undef READ_BYTE_FIELD
3554#undef WRITE_BYTE_FIELD
3555
3556
3557} } // namespace v8::internal
3558
3559#endif // V8_OBJECTS_INL_H_