blob: bac224f4e9fe044813e081dbba0592fe4a1e3ba6 [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
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000087#define SMI_ACCESSORS(holder, name, offset) \
88 int holder::name() { \
89 Object* value = READ_FIELD(this, offset); \
90 return Smi::cast(value)->value(); \
91 } \
92 void holder::set_##name(int value) { \
93 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
94 }
95
96
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000097#define BOOL_GETTER(holder, field, name, offset) \
98 bool holder::name() { \
99 return BooleanBit::get(field(), offset); \
100 } \
101
102
103#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104 bool holder::name() { \
105 return BooleanBit::get(field(), offset); \
106 } \
107 void holder::set_##name(bool value) { \
108 set_##field(BooleanBit::set(field(), offset, value)); \
109 }
110
111
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000112bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
113 // There is a constraint on the object; check.
114 if (!this->IsJSObject()) return false;
115 // Fetch the constructor function of the object.
116 Object* cons_obj = JSObject::cast(this)->map()->constructor();
117 if (!cons_obj->IsJSFunction()) return false;
118 JSFunction* fun = JSFunction::cast(cons_obj);
119 // Iterate through the chain of inheriting function templates to
120 // see if the required one occurs.
121 for (Object* type = fun->shared()->function_data();
122 type->IsFunctionTemplateInfo();
123 type = FunctionTemplateInfo::cast(type)->parent_template()) {
124 if (type == expected) return true;
125 }
126 // Didn't find the required type in the inheritance chain.
127 return false;
128}
129
130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131bool Object::IsSmi() {
132 return HAS_SMI_TAG(this);
133}
134
135
136bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000137 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000138}
139
140
141bool Object::IsHeapNumber() {
142 return Object::IsHeapObject()
143 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
144}
145
146
147bool Object::IsString() {
148 return Object::IsHeapObject()
149 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
150}
151
152
ager@chromium.org870a0b62008-11-04 11:43:05 +0000153bool Object::IsSymbol() {
154 if (!this->IsHeapObject()) return false;
155 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000156 // Because the symbol tag is non-zero and no non-string types have the
157 // symbol bit set we can test for symbols with a very simple test
158 // operation.
159 ASSERT(kSymbolTag != 0);
160 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
161 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000162}
163
164
165bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000166 if (!this->IsHeapObject()) return false;
167 uint32_t type = HeapObject::cast(this)->map()->instance_type();
168 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
169 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170}
171
172
ager@chromium.org870a0b62008-11-04 11:43:05 +0000173bool Object::IsSeqString() {
174 if (!IsString()) return false;
175 return StringShape(String::cast(this)).IsSequential();
176}
177
178
179bool Object::IsSeqAsciiString() {
180 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000181 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000182 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000183}
184
185
186bool Object::IsSeqTwoByteString() {
187 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000188 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000189 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190}
191
192
193bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000194 if (!IsString()) return false;
195 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196}
197
198
199bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000200 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000201 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000202 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000203}
204
205
206bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000207 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000208 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000209 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210}
211
212
ager@chromium.org870a0b62008-11-04 11:43:05 +0000213StringShape::StringShape(String* str)
214 : type_(str->map()->instance_type()) {
215 set_valid();
216 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220StringShape::StringShape(Map* map)
221 : type_(map->instance_type()) {
222 set_valid();
223 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224}
225
226
ager@chromium.org870a0b62008-11-04 11:43:05 +0000227StringShape::StringShape(InstanceType t)
228 : type_(static_cast<uint32_t>(t)) {
229 set_valid();
230 ASSERT((type_ & kIsNotStringMask) == kStringTag);
231}
232
233
234bool StringShape::IsSymbol() {
235 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000236 ASSERT(kSymbolTag != 0);
237 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000238}
239
240
ager@chromium.org5ec48922009-05-05 07:25:34 +0000241bool String::IsAsciiRepresentation() {
242 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000243 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000244}
245
246
ager@chromium.org5ec48922009-05-05 07:25:34 +0000247bool String::IsTwoByteRepresentation() {
248 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250}
251
252
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000253bool String::HasOnlyAsciiChars() {
254 uint32_t type = map()->instance_type();
255 return (type & kStringEncodingMask) == kAsciiStringTag ||
256 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000257}
258
259
ager@chromium.org870a0b62008-11-04 11:43:05 +0000260bool StringShape::IsCons() {
261 return (type_ & kStringRepresentationMask) == kConsStringTag;
262}
263
264
ager@chromium.org870a0b62008-11-04 11:43:05 +0000265bool StringShape::IsExternal() {
266 return (type_ & kStringRepresentationMask) == kExternalStringTag;
267}
268
269
270bool StringShape::IsSequential() {
271 return (type_ & kStringRepresentationMask) == kSeqStringTag;
272}
273
274
275StringRepresentationTag StringShape::representation_tag() {
276 uint32_t tag = (type_ & kStringRepresentationMask);
277 return static_cast<StringRepresentationTag>(tag);
278}
279
280
281uint32_t StringShape::full_representation_tag() {
282 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
283}
284
285
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000286STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
287 Internals::kFullStringRepresentationMask);
288
289
ager@chromium.org870a0b62008-11-04 11:43:05 +0000290bool StringShape::IsSequentialAscii() {
291 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
292}
293
294
295bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000296 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000297}
298
299
300bool StringShape::IsExternalAscii() {
301 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
302}
303
304
305bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000306 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000307}
308
309
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000310STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
311 Internals::kExternalTwoByteRepresentationTag);
312
313
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000314uc32 FlatStringReader::Get(int index) {
315 ASSERT(0 <= index && index <= length_);
316 if (is_ascii_) {
317 return static_cast<const byte*>(start_)[index];
318 } else {
319 return static_cast<const uc16*>(start_)[index];
320 }
321}
322
323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000324bool Object::IsNumber() {
325 return IsSmi() || IsHeapNumber();
326}
327
328
329bool Object::IsByteArray() {
330 return Object::IsHeapObject()
331 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
332}
333
334
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000335bool Object::IsPixelArray() {
336 return Object::IsHeapObject() &&
337 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
338}
339
340
ager@chromium.org3811b432009-10-28 14:53:37 +0000341bool Object::IsExternalArray() {
342 if (!Object::IsHeapObject())
343 return false;
344 InstanceType instance_type =
345 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000346 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
347 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000348}
349
350
351bool Object::IsExternalByteArray() {
352 return Object::IsHeapObject() &&
353 HeapObject::cast(this)->map()->instance_type() ==
354 EXTERNAL_BYTE_ARRAY_TYPE;
355}
356
357
358bool Object::IsExternalUnsignedByteArray() {
359 return Object::IsHeapObject() &&
360 HeapObject::cast(this)->map()->instance_type() ==
361 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
362}
363
364
365bool Object::IsExternalShortArray() {
366 return Object::IsHeapObject() &&
367 HeapObject::cast(this)->map()->instance_type() ==
368 EXTERNAL_SHORT_ARRAY_TYPE;
369}
370
371
372bool Object::IsExternalUnsignedShortArray() {
373 return Object::IsHeapObject() &&
374 HeapObject::cast(this)->map()->instance_type() ==
375 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
376}
377
378
379bool Object::IsExternalIntArray() {
380 return Object::IsHeapObject() &&
381 HeapObject::cast(this)->map()->instance_type() ==
382 EXTERNAL_INT_ARRAY_TYPE;
383}
384
385
386bool Object::IsExternalUnsignedIntArray() {
387 return Object::IsHeapObject() &&
388 HeapObject::cast(this)->map()->instance_type() ==
389 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
390}
391
392
393bool Object::IsExternalFloatArray() {
394 return Object::IsHeapObject() &&
395 HeapObject::cast(this)->map()->instance_type() ==
396 EXTERNAL_FLOAT_ARRAY_TYPE;
397}
398
399
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400bool Object::IsFailure() {
401 return HAS_FAILURE_TAG(this);
402}
403
404
405bool Object::IsRetryAfterGC() {
406 return HAS_FAILURE_TAG(this)
407 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
408}
409
410
ager@chromium.org7c537e22008-10-16 08:43:32 +0000411bool Object::IsOutOfMemoryFailure() {
412 return HAS_FAILURE_TAG(this)
413 && Failure::cast(this)->IsOutOfMemoryException();
414}
415
416
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417bool Object::IsException() {
418 return this == Failure::Exception();
419}
420
421
422bool Object::IsJSObject() {
423 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000424 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425}
426
427
ager@chromium.org32912102009-01-16 10:38:43 +0000428bool Object::IsJSContextExtensionObject() {
429 return IsHeapObject()
430 && (HeapObject::cast(this)->map()->instance_type() ==
431 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
432}
433
434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000435bool Object::IsMap() {
436 return Object::IsHeapObject()
437 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
438}
439
440
441bool Object::IsFixedArray() {
442 return Object::IsHeapObject()
443 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
444}
445
446
447bool Object::IsDescriptorArray() {
448 return IsFixedArray();
449}
450
451
452bool Object::IsContext() {
453 return Object::IsHeapObject()
454 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000455 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000456 HeapObject::cast(this)->map() == Heap::global_context_map());
457}
458
459
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000460bool Object::IsCatchContext() {
461 return Object::IsHeapObject()
462 && HeapObject::cast(this)->map() == Heap::catch_context_map();
463}
464
465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000466bool Object::IsGlobalContext() {
467 return Object::IsHeapObject()
468 && HeapObject::cast(this)->map() == Heap::global_context_map();
469}
470
471
472bool Object::IsJSFunction() {
473 return Object::IsHeapObject()
474 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
475}
476
477
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000478template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return obj->IsJSFunction();
480}
481
482
483bool Object::IsCode() {
484 return Object::IsHeapObject()
485 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
486}
487
488
489bool Object::IsOddball() {
490 return Object::IsHeapObject()
491 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
492}
493
494
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000495bool Object::IsJSGlobalPropertyCell() {
496 return Object::IsHeapObject()
497 && HeapObject::cast(this)->map()->instance_type()
498 == JS_GLOBAL_PROPERTY_CELL_TYPE;
499}
500
501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502bool Object::IsSharedFunctionInfo() {
503 return Object::IsHeapObject() &&
504 (HeapObject::cast(this)->map()->instance_type() ==
505 SHARED_FUNCTION_INFO_TYPE);
506}
507
508
509bool Object::IsJSValue() {
510 return Object::IsHeapObject()
511 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
512}
513
514
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000515bool Object::IsStringWrapper() {
516 return IsJSValue() && JSValue::cast(this)->value()->IsString();
517}
518
519
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000520bool Object::IsProxy() {
521 return Object::IsHeapObject()
522 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
523}
524
525
526bool Object::IsBoolean() {
527 return IsTrue() || IsFalse();
528}
529
530
531bool Object::IsJSArray() {
532 return Object::IsHeapObject()
533 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
534}
535
536
ager@chromium.org236ad962008-09-25 09:45:57 +0000537bool Object::IsJSRegExp() {
538 return Object::IsHeapObject()
539 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
540}
541
542
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000543template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000544 return obj->IsJSArray();
545}
546
547
548bool Object::IsHashTable() {
549 return Object::IsHeapObject()
550 && HeapObject::cast(this)->map() == Heap::hash_table_map();
551}
552
553
554bool Object::IsDictionary() {
555 return IsHashTable() && this != Heap::symbol_table();
556}
557
558
559bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000560 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561}
562
563
ager@chromium.orgac091b72010-05-05 07:34:42 +0000564bool Object::IsJSFunctionResultCache() {
565 if (!IsFixedArray()) return false;
566 FixedArray* self = FixedArray::cast(this);
567 int length = self->length();
568 if (length < JSFunctionResultCache::kEntriesIndex) return false;
569 if ((length - JSFunctionResultCache::kEntriesIndex)
570 % JSFunctionResultCache::kEntrySize != 0) {
571 return false;
572 }
573#ifdef DEBUG
574 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
575#endif
576 return true;
577}
578
579
ricow@chromium.org65fae842010-08-25 15:26:24 +0000580bool Object::IsNormalizedMapCache() {
581 if (!IsFixedArray()) return false;
582 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
583 return false;
584 }
585#ifdef DEBUG
586 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
587#endif
588 return true;
589}
590
591
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000592bool Object::IsCompilationCacheTable() {
593 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000594}
595
596
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000597bool Object::IsCodeCacheHashTable() {
598 return IsHashTable();
599}
600
601
ager@chromium.org236ad962008-09-25 09:45:57 +0000602bool Object::IsMapCache() {
603 return IsHashTable();
604}
605
606
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607bool Object::IsPrimitive() {
608 return IsOddball() || IsNumber() || IsString();
609}
610
611
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000612bool Object::IsJSGlobalProxy() {
613 bool result = IsHeapObject() &&
614 (HeapObject::cast(this)->map()->instance_type() ==
615 JS_GLOBAL_PROXY_TYPE);
616 ASSERT(!result || IsAccessCheckNeeded());
617 return result;
618}
619
620
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000621bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000622 if (!IsHeapObject()) return false;
623
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000624 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000625 return type == JS_GLOBAL_OBJECT_TYPE ||
626 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627}
628
629
630bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631 return IsHeapObject() &&
632 (HeapObject::cast(this)->map()->instance_type() ==
633 JS_GLOBAL_OBJECT_TYPE);
634}
635
636
637bool Object::IsJSBuiltinsObject() {
638 return IsHeapObject() &&
639 (HeapObject::cast(this)->map()->instance_type() ==
640 JS_BUILTINS_OBJECT_TYPE);
641}
642
643
644bool Object::IsUndetectableObject() {
645 return IsHeapObject()
646 && HeapObject::cast(this)->map()->is_undetectable();
647}
648
649
650bool Object::IsAccessCheckNeeded() {
651 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000652 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000653}
654
655
656bool Object::IsStruct() {
657 if (!IsHeapObject()) return false;
658 switch (HeapObject::cast(this)->map()->instance_type()) {
659#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
660 STRUCT_LIST(MAKE_STRUCT_CASE)
661#undef MAKE_STRUCT_CASE
662 default: return false;
663 }
664}
665
666
667#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
668 bool Object::Is##Name() { \
669 return Object::IsHeapObject() \
670 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
671 }
672 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
673#undef MAKE_STRUCT_PREDICATE
674
675
676bool Object::IsUndefined() {
677 return this == Heap::undefined_value();
678}
679
680
681bool Object::IsTheHole() {
682 return this == Heap::the_hole_value();
683}
684
685
686bool Object::IsNull() {
687 return this == Heap::null_value();
688}
689
690
691bool Object::IsTrue() {
692 return this == Heap::true_value();
693}
694
695
696bool Object::IsFalse() {
697 return this == Heap::false_value();
698}
699
700
701double Object::Number() {
702 ASSERT(IsNumber());
703 return IsSmi()
704 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
705 : reinterpret_cast<HeapNumber*>(this)->value();
706}
707
708
709
710Object* Object::ToSmi() {
711 if (IsSmi()) return this;
712 if (IsHeapNumber()) {
713 double value = HeapNumber::cast(this)->value();
714 int int_value = FastD2I(value);
715 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
716 return Smi::FromInt(int_value);
717 }
718 }
719 return Failure::Exception();
720}
721
722
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000723bool Object::HasSpecificClassOf(String* name) {
724 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
725}
726
727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728Object* Object::GetElement(uint32_t index) {
729 return GetElementWithReceiver(this, index);
730}
731
732
733Object* Object::GetProperty(String* key) {
734 PropertyAttributes attributes;
735 return GetPropertyWithReceiver(this, key, &attributes);
736}
737
738
739Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
740 return GetPropertyWithReceiver(this, key, attributes);
741}
742
743
744#define FIELD_ADDR(p, offset) \
745 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
746
747#define READ_FIELD(p, offset) \
748 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
749
750#define WRITE_FIELD(p, offset, value) \
751 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
752
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000753
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754#define WRITE_BARRIER(object, offset) \
755 Heap::RecordWrite(object->address(), offset);
756
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000757// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758// write due to the assert validating the written value.
759#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
760 if (mode == UPDATE_WRITE_BARRIER) { \
761 Heap::RecordWrite(object->address(), offset); \
762 } else { \
763 ASSERT(mode == SKIP_WRITE_BARRIER); \
764 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000765 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000766 Page::FromAddress(object->address())-> \
767 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000768 }
769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770#define READ_DOUBLE_FIELD(p, offset) \
771 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
772
773#define WRITE_DOUBLE_FIELD(p, offset, value) \
774 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
775
776#define READ_INT_FIELD(p, offset) \
777 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
778
779#define WRITE_INT_FIELD(p, offset, value) \
780 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
781
ager@chromium.org3e875802009-06-29 08:26:34 +0000782#define READ_INTPTR_FIELD(p, offset) \
783 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
784
785#define WRITE_INTPTR_FIELD(p, offset, value) \
786 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
787
ager@chromium.org7c537e22008-10-16 08:43:32 +0000788#define READ_UINT32_FIELD(p, offset) \
789 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
790
791#define WRITE_UINT32_FIELD(p, offset, value) \
792 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
793
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794#define READ_SHORT_FIELD(p, offset) \
795 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
796
797#define WRITE_SHORT_FIELD(p, offset, value) \
798 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
799
800#define READ_BYTE_FIELD(p, offset) \
801 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
802
803#define WRITE_BYTE_FIELD(p, offset, value) \
804 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
805
806
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000807Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
808 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
812int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000813 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814}
815
816
817Smi* Smi::FromInt(int value) {
818 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000819 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000820 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000821 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000822 return reinterpret_cast<Smi*>(tagged_value);
823}
824
825
826Smi* Smi::FromIntptr(intptr_t value) {
827 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000828 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
829 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830}
831
832
833Failure::Type Failure::type() const {
834 return static_cast<Type>(value() & kFailureTypeTagMask);
835}
836
837
838bool Failure::IsInternalError() const {
839 return type() == INTERNAL_ERROR;
840}
841
842
843bool Failure::IsOutOfMemoryException() const {
844 return type() == OUT_OF_MEMORY_EXCEPTION;
845}
846
847
848int Failure::requested() const {
849 const int kShiftBits =
850 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
851 STATIC_ASSERT(kShiftBits >= 0);
852 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000853 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000854}
855
856
857AllocationSpace Failure::allocation_space() const {
858 ASSERT_EQ(RETRY_AFTER_GC, type());
859 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
860 & kSpaceTagMask);
861}
862
863
864Failure* Failure::InternalError() {
865 return Construct(INTERNAL_ERROR);
866}
867
868
869Failure* Failure::Exception() {
870 return Construct(EXCEPTION);
871}
872
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000873
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000874Failure* Failure::OutOfMemoryException() {
875 return Construct(OUT_OF_MEMORY_EXCEPTION);
876}
877
878
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000879intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000880 return static_cast<intptr_t>(
881 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882}
883
884
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000886 // Assert that the space encoding fits in the three bytes allotted for it.
887 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000888 uintptr_t requested =
889 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
890 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000891 if (((requested << tag_bits) >> tag_bits) != requested) {
892 // No room for entire requested size in the bits. Round down to
893 // maximally representable size.
894 requested = static_cast<intptr_t>(
895 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
896 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000897 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000898 return Construct(RETRY_AFTER_GC, value);
899}
900
901
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000902Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000903 uintptr_t info =
904 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000905 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000906 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907}
908
909
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000910bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000911#ifdef DEBUG
912 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
913#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000914
915#ifdef V8_TARGET_ARCH_X64
916 // To be representable as a long smi, the value must be a 32-bit integer.
917 bool result = (value == static_cast<int32_t>(value));
918#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000919 // To be representable as an tagged small integer, the two
920 // most-significant bits of 'value' must be either 00 or 11 due to
921 // sign-extension. To check this we add 01 to the two
922 // most-significant bits, and check if the most-significant bit is 0
923 //
924 // CAUTION: The original code below:
925 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
926 // may lead to incorrect results according to the C language spec, and
927 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
928 // compiler may produce undefined results in case of signed integer
929 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000930 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000931#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000932 ASSERT(result == in_range);
933 return result;
934}
935
936
kasper.lund7276f142008-07-30 08:49:36 +0000937MapWord MapWord::FromMap(Map* map) {
938 return MapWord(reinterpret_cast<uintptr_t>(map));
939}
940
941
942Map* MapWord::ToMap() {
943 return reinterpret_cast<Map*>(value_);
944}
945
946
947bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000948 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000949}
950
951
952MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000953 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
954 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000955}
956
957
958HeapObject* MapWord::ToForwardingAddress() {
959 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000960 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000961}
962
963
964bool MapWord::IsMarked() {
965 return (value_ & kMarkingMask) == 0;
966}
967
968
969void MapWord::SetMark() {
970 value_ &= ~kMarkingMask;
971}
972
973
974void MapWord::ClearMark() {
975 value_ |= kMarkingMask;
976}
977
978
979bool MapWord::IsOverflowed() {
980 return (value_ & kOverflowMask) != 0;
981}
982
983
984void MapWord::SetOverflow() {
985 value_ |= kOverflowMask;
986}
987
988
989void MapWord::ClearOverflow() {
990 value_ &= ~kOverflowMask;
991}
992
993
994MapWord MapWord::EncodeAddress(Address map_address, int offset) {
995 // Offset is the distance in live bytes from the first live object in the
996 // same page. The offset between two objects in the same page should not
997 // exceed the object area size of a page.
998 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
999
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001000 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001001 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1002
1003 Page* map_page = Page::FromAddress(map_address);
1004 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1005
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001006 uintptr_t map_page_offset =
1007 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001008
1009 uintptr_t encoding =
1010 (compact_offset << kForwardingOffsetShift) |
1011 (map_page_offset << kMapPageOffsetShift) |
1012 (map_page->mc_page_index << kMapPageIndexShift);
1013 return MapWord(encoding);
1014}
1015
1016
1017Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 int map_page_index =
1019 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001020 ASSERT_MAP_PAGE_INDEX(map_page_index);
1021
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001022 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001023 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1024 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001025
1026 return (map_space->PageAddress(map_page_index) + map_page_offset);
1027}
1028
1029
1030int MapWord::DecodeOffset() {
1031 // The offset field is represented in the kForwardingOffsetBits
1032 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001033 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1034 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1035 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001036}
1037
1038
1039MapWord MapWord::FromEncodedAddress(Address address) {
1040 return MapWord(reinterpret_cast<uintptr_t>(address));
1041}
1042
1043
1044Address MapWord::ToEncodedAddress() {
1045 return reinterpret_cast<Address>(value_);
1046}
1047
1048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049#ifdef DEBUG
1050void HeapObject::VerifyObjectField(int offset) {
1051 VerifyPointer(READ_FIELD(this, offset));
1052}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001053
1054void HeapObject::VerifySmiField(int offset) {
1055 ASSERT(READ_FIELD(this, offset)->IsSmi());
1056}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001057#endif
1058
1059
1060Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001061 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001062}
1063
1064
1065void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001066 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067}
1068
1069
kasper.lund7276f142008-07-30 08:49:36 +00001070MapWord HeapObject::map_word() {
1071 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1072}
1073
1074
1075void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001076 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001077 // here.
1078 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1079}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001080
1081
1082HeapObject* HeapObject::FromAddress(Address address) {
1083 ASSERT_TAG_ALIGNED(address);
1084 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1085}
1086
1087
1088Address HeapObject::address() {
1089 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1090}
1091
1092
1093int HeapObject::Size() {
1094 return SizeFromMap(map());
1095}
1096
1097
1098void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1099 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1100 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1101}
1102
1103
1104void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1105 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1106}
1107
1108
kasper.lund7276f142008-07-30 08:49:36 +00001109bool HeapObject::IsMarked() {
1110 return map_word().IsMarked();
1111}
1112
1113
1114void HeapObject::SetMark() {
1115 ASSERT(!IsMarked());
1116 MapWord first_word = map_word();
1117 first_word.SetMark();
1118 set_map_word(first_word);
1119}
1120
1121
1122void HeapObject::ClearMark() {
1123 ASSERT(IsMarked());
1124 MapWord first_word = map_word();
1125 first_word.ClearMark();
1126 set_map_word(first_word);
1127}
1128
1129
1130bool HeapObject::IsOverflowed() {
1131 return map_word().IsOverflowed();
1132}
1133
1134
1135void HeapObject::SetOverflow() {
1136 MapWord first_word = map_word();
1137 first_word.SetOverflow();
1138 set_map_word(first_word);
1139}
1140
1141
1142void HeapObject::ClearOverflow() {
1143 ASSERT(IsOverflowed());
1144 MapWord first_word = map_word();
1145 first_word.ClearOverflow();
1146 set_map_word(first_word);
1147}
1148
1149
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001150double HeapNumber::value() {
1151 return READ_DOUBLE_FIELD(this, kValueOffset);
1152}
1153
1154
1155void HeapNumber::set_value(double value) {
1156 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1157}
1158
1159
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001160int HeapNumber::get_exponent() {
1161 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1162 kExponentShift) - kExponentBias;
1163}
1164
1165
1166int HeapNumber::get_sign() {
1167 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1168}
1169
1170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001171ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001172
1173
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001174HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001175 Object* array = READ_FIELD(this, kElementsOffset);
1176 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001177 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1178 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001179 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001180}
1181
1182
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001183void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001184 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001185 (value->map() == Heap::fixed_array_map() ||
1186 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001187 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001188 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1189 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001190 WRITE_FIELD(this, kElementsOffset, value);
1191 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1192}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193
1194
1195void JSObject::initialize_properties() {
1196 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1197 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1198}
1199
1200
1201void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001202 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001203 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1204 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1205}
1206
1207
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001208Object* JSObject::ResetElements() {
1209 Object* obj = map()->GetFastElementsMap();
1210 if (obj->IsFailure()) return obj;
1211 set_map(Map::cast(obj));
1212 initialize_elements();
1213 return this;
1214}
1215
1216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217ACCESSORS(Oddball, to_string, String, kToStringOffset)
1218ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1219
1220
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001221Object* JSGlobalPropertyCell::value() {
1222 return READ_FIELD(this, kValueOffset);
1223}
1224
1225
1226void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1227 // The write barrier is not used for global property cells.
1228 ASSERT(!val->IsJSGlobalPropertyCell());
1229 WRITE_FIELD(this, kValueOffset, val);
1230}
1231
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001234 InstanceType type = map()->instance_type();
1235 // Check for the most common kind of JavaScript object before
1236 // falling into the generic switch. This speeds up the internal
1237 // field operations considerably on average.
1238 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1239 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001240 case JS_GLOBAL_PROXY_TYPE:
1241 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242 case JS_GLOBAL_OBJECT_TYPE:
1243 return JSGlobalObject::kSize;
1244 case JS_BUILTINS_OBJECT_TYPE:
1245 return JSBuiltinsObject::kSize;
1246 case JS_FUNCTION_TYPE:
1247 return JSFunction::kSize;
1248 case JS_VALUE_TYPE:
1249 return JSValue::kSize;
1250 case JS_ARRAY_TYPE:
1251 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001252 case JS_REGEXP_TYPE:
1253 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001254 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255 return JSObject::kHeaderSize;
1256 default:
1257 UNREACHABLE();
1258 return 0;
1259 }
1260}
1261
1262
1263int JSObject::GetInternalFieldCount() {
1264 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001265 // Make sure to adjust for the number of in-object properties. These
1266 // properties do contribute to the size, but are not internal fields.
1267 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1268 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269}
1270
1271
1272Object* JSObject::GetInternalField(int index) {
1273 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001274 // Internal objects do follow immediately after the header, whereas in-object
1275 // properties are at the end of the object. Therefore there is no need
1276 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001277 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1278}
1279
1280
1281void JSObject::SetInternalField(int index, Object* value) {
1282 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001283 // Internal objects do follow immediately after the header, whereas in-object
1284 // properties are at the end of the object. Therefore there is no need
1285 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001286 int offset = GetHeaderSize() + (kPointerSize * index);
1287 WRITE_FIELD(this, offset, value);
1288 WRITE_BARRIER(this, offset);
1289}
1290
1291
ager@chromium.org7c537e22008-10-16 08:43:32 +00001292// Access fast-case object properties at index. The use of these routines
1293// is needed to correctly distinguish between properties stored in-object and
1294// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001295Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001296 // Adjust for the number of properties stored in the object.
1297 index -= map()->inobject_properties();
1298 if (index < 0) {
1299 int offset = map()->instance_size() + (index * kPointerSize);
1300 return READ_FIELD(this, offset);
1301 } else {
1302 ASSERT(index < properties()->length());
1303 return properties()->get(index);
1304 }
1305}
1306
1307
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001308Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001309 // Adjust for the number of properties stored in the object.
1310 index -= map()->inobject_properties();
1311 if (index < 0) {
1312 int offset = map()->instance_size() + (index * kPointerSize);
1313 WRITE_FIELD(this, offset, value);
1314 WRITE_BARRIER(this, offset);
1315 } else {
1316 ASSERT(index < properties()->length());
1317 properties()->set(index, value);
1318 }
1319 return value;
1320}
1321
1322
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001323Object* JSObject::InObjectPropertyAt(int index) {
1324 // Adjust for the number of properties stored in the object.
1325 index -= map()->inobject_properties();
1326 ASSERT(index < 0);
1327 int offset = map()->instance_size() + (index * kPointerSize);
1328 return READ_FIELD(this, offset);
1329}
1330
1331
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001332Object* JSObject::InObjectPropertyAtPut(int index,
1333 Object* value,
1334 WriteBarrierMode mode) {
1335 // Adjust for the number of properties stored in the object.
1336 index -= map()->inobject_properties();
1337 ASSERT(index < 0);
1338 int offset = map()->instance_size() + (index * kPointerSize);
1339 WRITE_FIELD(this, offset, value);
1340 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1341 return value;
1342}
1343
1344
1345
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001347 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001348 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001349 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350 }
1351}
1352
1353
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001354bool JSObject::HasFastProperties() {
1355 return !properties()->IsDictionary();
1356}
1357
1358
1359int JSObject::MaxFastProperties() {
1360 // Allow extra fast properties if the object has more than
1361 // kMaxFastProperties in-object properties. When this is the case,
1362 // it is very unlikely that the object is being used as a dictionary
1363 // and there is a good chance that allowing more map transitions
1364 // will be worth it.
1365 return Max(map()->inobject_properties(), kMaxFastProperties);
1366}
1367
1368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001369void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001370 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001371 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001372 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373 }
1374}
1375
1376
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001377bool Object::ToArrayIndex(uint32_t* index) {
1378 if (IsSmi()) {
1379 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 if (value < 0) return false;
1381 *index = value;
1382 return true;
1383 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001384 if (IsHeapNumber()) {
1385 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386 uint32_t uint_value = static_cast<uint32_t>(value);
1387 if (value == static_cast<double>(uint_value)) {
1388 *index = uint_value;
1389 return true;
1390 }
1391 }
1392 return false;
1393}
1394
1395
1396bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1397 if (!this->IsJSValue()) return false;
1398
1399 JSValue* js_value = JSValue::cast(this);
1400 if (!js_value->value()->IsString()) return false;
1401
1402 String* str = String::cast(js_value->value());
1403 if (index >= (uint32_t)str->length()) return false;
1404
1405 return true;
1406}
1407
1408
1409Object* FixedArray::get(int index) {
1410 ASSERT(index >= 0 && index < this->length());
1411 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1412}
1413
1414
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001415void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001416 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001417 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1418 int offset = kHeaderSize + index * kPointerSize;
1419 WRITE_FIELD(this, offset, value);
1420}
1421
1422
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001424 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425 ASSERT(index >= 0 && index < this->length());
1426 int offset = kHeaderSize + index * kPointerSize;
1427 WRITE_FIELD(this, offset, value);
1428 WRITE_BARRIER(this, offset);
1429}
1430
1431
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001432WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1434 return UPDATE_WRITE_BARRIER;
1435}
1436
1437
1438void FixedArray::set(int index,
1439 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001440 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001441 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442 ASSERT(index >= 0 && index < this->length());
1443 int offset = kHeaderSize + index * kPointerSize;
1444 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001445 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446}
1447
1448
1449void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001450 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001452 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1454}
1455
1456
1457void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001458 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459 ASSERT(index >= 0 && index < this->length());
1460 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1461 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1462 Heap::undefined_value());
1463}
1464
1465
ager@chromium.org236ad962008-09-25 09:45:57 +00001466void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001467 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001468 ASSERT(index >= 0 && index < this->length());
1469 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1470 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1471}
1472
1473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001475 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001476 ASSERT(index >= 0 && index < this->length());
1477 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1478 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1479}
1480
1481
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001482void FixedArray::set_unchecked(int index, Smi* value) {
1483 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1484 int offset = kHeaderSize + index * kPointerSize;
1485 WRITE_FIELD(this, offset, value);
1486}
1487
1488
1489void FixedArray::set_null_unchecked(int index) {
1490 ASSERT(index >= 0 && index < this->length());
1491 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1492 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1493}
1494
1495
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001496Object** FixedArray::data_start() {
1497 return HeapObject::RawField(this, kHeaderSize);
1498}
1499
1500
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001501bool DescriptorArray::IsEmpty() {
1502 ASSERT(this == Heap::empty_descriptor_array() ||
1503 this->length() > 2);
1504 return this == Heap::empty_descriptor_array();
1505}
1506
1507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001508void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1509 Object* tmp = array->get(first);
1510 fast_set(array, first, array->get(second));
1511 fast_set(array, second, tmp);
1512}
1513
1514
1515int DescriptorArray::Search(String* name) {
1516 SLOW_ASSERT(IsSortedNoDuplicates());
1517
1518 // Check for empty descriptor array.
1519 int nof = number_of_descriptors();
1520 if (nof == 0) return kNotFound;
1521
1522 // Fast case: do linear search for small arrays.
1523 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001524 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001525 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001526 }
1527
1528 // Slow case: perform binary search.
1529 return BinarySearch(name, 0, nof - 1);
1530}
1531
1532
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001533int DescriptorArray::SearchWithCache(String* name) {
1534 int number = DescriptorLookupCache::Lookup(this, name);
1535 if (number == DescriptorLookupCache::kAbsent) {
1536 number = Search(name);
1537 DescriptorLookupCache::Update(this, name, number);
1538 }
1539 return number;
1540}
1541
1542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001543String* DescriptorArray::GetKey(int descriptor_number) {
1544 ASSERT(descriptor_number < number_of_descriptors());
1545 return String::cast(get(ToKeyIndex(descriptor_number)));
1546}
1547
1548
1549Object* DescriptorArray::GetValue(int descriptor_number) {
1550 ASSERT(descriptor_number < number_of_descriptors());
1551 return GetContentArray()->get(ToValueIndex(descriptor_number));
1552}
1553
1554
1555Smi* DescriptorArray::GetDetails(int descriptor_number) {
1556 ASSERT(descriptor_number < number_of_descriptors());
1557 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1558}
1559
1560
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001561PropertyType DescriptorArray::GetType(int descriptor_number) {
1562 ASSERT(descriptor_number < number_of_descriptors());
1563 return PropertyDetails(GetDetails(descriptor_number)).type();
1564}
1565
1566
1567int DescriptorArray::GetFieldIndex(int descriptor_number) {
1568 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1569}
1570
1571
1572JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1573 return JSFunction::cast(GetValue(descriptor_number));
1574}
1575
1576
1577Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1578 ASSERT(GetType(descriptor_number) == CALLBACKS);
1579 return GetValue(descriptor_number);
1580}
1581
1582
1583AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1584 ASSERT(GetType(descriptor_number) == CALLBACKS);
1585 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1586 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1587}
1588
1589
1590bool DescriptorArray::IsProperty(int descriptor_number) {
1591 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1592}
1593
1594
1595bool DescriptorArray::IsTransition(int descriptor_number) {
1596 PropertyType t = GetType(descriptor_number);
1597 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1598}
1599
1600
1601bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1602 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1603}
1604
1605
1606bool DescriptorArray::IsDontEnum(int descriptor_number) {
1607 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1608}
1609
1610
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001611void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1612 desc->Init(GetKey(descriptor_number),
1613 GetValue(descriptor_number),
1614 GetDetails(descriptor_number));
1615}
1616
1617
1618void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1619 // Range check.
1620 ASSERT(descriptor_number < number_of_descriptors());
1621
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001622 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1624 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1625
1626 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1627 FixedArray* content_array = GetContentArray();
1628 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1629 fast_set(content_array, ToDetailsIndex(descriptor_number),
1630 desc->GetDetails().AsSmi());
1631}
1632
1633
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001634void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1635 Descriptor desc;
1636 src->Get(src_index, &desc);
1637 Set(index, &desc);
1638}
1639
1640
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001641void DescriptorArray::Swap(int first, int second) {
1642 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1643 FixedArray* content_array = GetContentArray();
1644 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1645 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1646}
1647
1648
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001649bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001650 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651 if (!max_index_object->IsSmi()) return false;
1652 return 0 !=
1653 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1654}
1655
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001656uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001657 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001658 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001659 if (!max_index_object->IsSmi()) return 0;
1660 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1661 return value >> kRequiresSlowElementsTagSize;
1662}
1663
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001664void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001665 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001666}
1667
1668
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669// ------------------------------------
1670// Cast operations
1671
1672
1673CAST_ACCESSOR(FixedArray)
1674CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001675CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001676CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001677CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001678CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001679CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001680CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681CAST_ACCESSOR(String)
1682CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001683CAST_ACCESSOR(SeqAsciiString)
1684CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001685CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001686CAST_ACCESSOR(ExternalString)
1687CAST_ACCESSOR(ExternalAsciiString)
1688CAST_ACCESSOR(ExternalTwoByteString)
1689CAST_ACCESSOR(JSObject)
1690CAST_ACCESSOR(Smi)
1691CAST_ACCESSOR(Failure)
1692CAST_ACCESSOR(HeapObject)
1693CAST_ACCESSOR(HeapNumber)
1694CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001695CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696CAST_ACCESSOR(SharedFunctionInfo)
1697CAST_ACCESSOR(Map)
1698CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001699CAST_ACCESSOR(GlobalObject)
1700CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701CAST_ACCESSOR(JSGlobalObject)
1702CAST_ACCESSOR(JSBuiltinsObject)
1703CAST_ACCESSOR(Code)
1704CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001705CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001706CAST_ACCESSOR(Proxy)
1707CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001708CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001709CAST_ACCESSOR(ExternalArray)
1710CAST_ACCESSOR(ExternalByteArray)
1711CAST_ACCESSOR(ExternalUnsignedByteArray)
1712CAST_ACCESSOR(ExternalShortArray)
1713CAST_ACCESSOR(ExternalUnsignedShortArray)
1714CAST_ACCESSOR(ExternalIntArray)
1715CAST_ACCESSOR(ExternalUnsignedIntArray)
1716CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001717CAST_ACCESSOR(Struct)
1718
1719
1720#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1721 STRUCT_LIST(MAKE_STRUCT_CAST)
1722#undef MAKE_STRUCT_CAST
1723
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001724
1725template <typename Shape, typename Key>
1726HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727 ASSERT(obj->IsHashTable());
1728 return reinterpret_cast<HashTable*>(obj);
1729}
1730
1731
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001732SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1733SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1734
1735INT_ACCESSORS(PixelArray, length, kLengthOffset)
1736INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737
1738
ager@chromium.orgac091b72010-05-05 07:34:42 +00001739SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001740
1741
1742uint32_t String::hash_field() {
1743 return READ_UINT32_FIELD(this, kHashFieldOffset);
1744}
1745
1746
1747void String::set_hash_field(uint32_t value) {
1748 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001749#if V8_HOST_ARCH_64_BIT
1750 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1751#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001752}
1753
1754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001755bool String::Equals(String* other) {
1756 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001757 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1758 return false;
1759 }
1760 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761}
1762
1763
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001764Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001765 if (!StringShape(this).IsCons()) return this;
1766 ConsString* cons = ConsString::cast(this);
1767 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001768 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769}
1770
1771
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001772String* String::TryFlattenGetString(PretenureFlag pretenure) {
1773 Object* flat = TryFlatten(pretenure);
1774 return flat->IsFailure() ? this : String::cast(flat);
1775}
1776
1777
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001778uint16_t String::Get(int index) {
1779 ASSERT(index >= 0 && index < length());
1780 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001781 case kSeqStringTag | kAsciiStringTag:
1782 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1783 case kSeqStringTag | kTwoByteStringTag:
1784 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1785 case kConsStringTag | kAsciiStringTag:
1786 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001788 case kExternalStringTag | kAsciiStringTag:
1789 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1790 case kExternalStringTag | kTwoByteStringTag:
1791 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 default:
1793 break;
1794 }
1795
1796 UNREACHABLE();
1797 return 0;
1798}
1799
1800
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001801void String::Set(int index, uint16_t value) {
1802 ASSERT(index >= 0 && index < length());
1803 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804
ager@chromium.org5ec48922009-05-05 07:25:34 +00001805 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001806 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1807 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808}
1809
1810
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001811bool String::IsFlat() {
1812 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001813 case kConsStringTag: {
1814 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001815 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001816 return second->length() == 0;
1817 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001818 default:
1819 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 }
1821}
1822
1823
ager@chromium.org7c537e22008-10-16 08:43:32 +00001824uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001825 ASSERT(index >= 0 && index < length());
1826 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1827}
1828
1829
ager@chromium.org7c537e22008-10-16 08:43:32 +00001830void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1832 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1833 static_cast<byte>(value));
1834}
1835
1836
ager@chromium.org7c537e22008-10-16 08:43:32 +00001837Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838 return FIELD_ADDR(this, kHeaderSize);
1839}
1840
1841
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001842char* SeqAsciiString::GetChars() {
1843 return reinterpret_cast<char*>(GetCharsAddress());
1844}
1845
1846
ager@chromium.org7c537e22008-10-16 08:43:32 +00001847Address SeqTwoByteString::GetCharsAddress() {
1848 return FIELD_ADDR(this, kHeaderSize);
1849}
1850
1851
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001852uc16* SeqTwoByteString::GetChars() {
1853 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1854}
1855
1856
ager@chromium.org7c537e22008-10-16 08:43:32 +00001857uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001858 ASSERT(index >= 0 && index < length());
1859 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1860}
1861
1862
ager@chromium.org7c537e22008-10-16 08:43:32 +00001863void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001864 ASSERT(index >= 0 && index < length());
1865 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1866}
1867
1868
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001869int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001870 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001871}
1872
1873
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001874int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001875 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876}
1877
1878
ager@chromium.org870a0b62008-11-04 11:43:05 +00001879String* ConsString::first() {
1880 return String::cast(READ_FIELD(this, kFirstOffset));
1881}
1882
1883
1884Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885 return READ_FIELD(this, kFirstOffset);
1886}
1887
1888
ager@chromium.org870a0b62008-11-04 11:43:05 +00001889void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001891 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001892}
1893
1894
ager@chromium.org870a0b62008-11-04 11:43:05 +00001895String* ConsString::second() {
1896 return String::cast(READ_FIELD(this, kSecondOffset));
1897}
1898
1899
1900Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901 return READ_FIELD(this, kSecondOffset);
1902}
1903
1904
ager@chromium.org870a0b62008-11-04 11:43:05 +00001905void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001907 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908}
1909
1910
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1912 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1913}
1914
1915
1916void ExternalAsciiString::set_resource(
1917 ExternalAsciiString::Resource* resource) {
1918 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1919}
1920
1921
1922ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1923 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1924}
1925
1926
1927void ExternalTwoByteString::set_resource(
1928 ExternalTwoByteString::Resource* resource) {
1929 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1930}
1931
1932
ager@chromium.orgac091b72010-05-05 07:34:42 +00001933void JSFunctionResultCache::MakeZeroSize() {
1934 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1935 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1936}
1937
1938
1939void JSFunctionResultCache::Clear() {
1940 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1941 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1942 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1943 MakeZeroSize();
1944}
1945
1946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947byte ByteArray::get(int index) {
1948 ASSERT(index >= 0 && index < this->length());
1949 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1950}
1951
1952
1953void ByteArray::set(int index, byte value) {
1954 ASSERT(index >= 0 && index < this->length());
1955 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1956}
1957
1958
1959int ByteArray::get_int(int index) {
1960 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1961 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1962}
1963
1964
1965ByteArray* ByteArray::FromDataStartAddress(Address address) {
1966 ASSERT_TAG_ALIGNED(address);
1967 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1968}
1969
1970
1971Address ByteArray::GetDataStartAddress() {
1972 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1973}
1974
1975
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001976uint8_t* PixelArray::external_pointer() {
1977 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1978 return reinterpret_cast<uint8_t*>(ptr);
1979}
1980
1981
1982void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1983 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1984 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1985}
1986
1987
1988uint8_t PixelArray::get(int index) {
1989 ASSERT((index >= 0) && (index < this->length()));
1990 uint8_t* ptr = external_pointer();
1991 return ptr[index];
1992}
1993
1994
1995void PixelArray::set(int index, uint8_t value) {
1996 ASSERT((index >= 0) && (index < this->length()));
1997 uint8_t* ptr = external_pointer();
1998 ptr[index] = value;
1999}
2000
2001
ager@chromium.org3811b432009-10-28 14:53:37 +00002002void* ExternalArray::external_pointer() {
2003 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2004 return reinterpret_cast<void*>(ptr);
2005}
2006
2007
2008void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2009 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2010 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2011}
2012
2013
2014int8_t ExternalByteArray::get(int index) {
2015 ASSERT((index >= 0) && (index < this->length()));
2016 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2017 return ptr[index];
2018}
2019
2020
2021void ExternalByteArray::set(int index, int8_t value) {
2022 ASSERT((index >= 0) && (index < this->length()));
2023 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2024 ptr[index] = value;
2025}
2026
2027
2028uint8_t ExternalUnsignedByteArray::get(int index) {
2029 ASSERT((index >= 0) && (index < this->length()));
2030 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2031 return ptr[index];
2032}
2033
2034
2035void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2036 ASSERT((index >= 0) && (index < this->length()));
2037 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2038 ptr[index] = value;
2039}
2040
2041
2042int16_t ExternalShortArray::get(int index) {
2043 ASSERT((index >= 0) && (index < this->length()));
2044 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2045 return ptr[index];
2046}
2047
2048
2049void ExternalShortArray::set(int index, int16_t value) {
2050 ASSERT((index >= 0) && (index < this->length()));
2051 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2052 ptr[index] = value;
2053}
2054
2055
2056uint16_t ExternalUnsignedShortArray::get(int index) {
2057 ASSERT((index >= 0) && (index < this->length()));
2058 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2059 return ptr[index];
2060}
2061
2062
2063void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2064 ASSERT((index >= 0) && (index < this->length()));
2065 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2066 ptr[index] = value;
2067}
2068
2069
2070int32_t ExternalIntArray::get(int index) {
2071 ASSERT((index >= 0) && (index < this->length()));
2072 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2073 return ptr[index];
2074}
2075
2076
2077void ExternalIntArray::set(int index, int32_t value) {
2078 ASSERT((index >= 0) && (index < this->length()));
2079 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2080 ptr[index] = value;
2081}
2082
2083
2084uint32_t ExternalUnsignedIntArray::get(int index) {
2085 ASSERT((index >= 0) && (index < this->length()));
2086 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2087 return ptr[index];
2088}
2089
2090
2091void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2092 ASSERT((index >= 0) && (index < this->length()));
2093 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2094 ptr[index] = value;
2095}
2096
2097
2098float ExternalFloatArray::get(int index) {
2099 ASSERT((index >= 0) && (index < this->length()));
2100 float* ptr = static_cast<float*>(external_pointer());
2101 return ptr[index];
2102}
2103
2104
2105void ExternalFloatArray::set(int index, float value) {
2106 ASSERT((index >= 0) && (index < this->length()));
2107 float* ptr = static_cast<float*>(external_pointer());
2108 ptr[index] = value;
2109}
2110
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002111
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002112int Map::visitor_id() {
2113 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2114}
2115
2116
2117void Map::set_visitor_id(int id) {
2118 ASSERT(0 <= id && id < 256);
2119 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2120}
2121
ager@chromium.org3811b432009-10-28 14:53:37 +00002122
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002124 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2125}
2126
2127
2128int Map::inobject_properties() {
2129 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130}
2131
2132
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002133int Map::pre_allocated_property_fields() {
2134 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2135}
2136
2137
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002139 int instance_size = map->instance_size();
2140 if (instance_size != kVariableSizeSentinel) return instance_size;
2141 // We can ignore the "symbol" bit becase it is only set for symbols
2142 // and implies a string type.
2143 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002144 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002146 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002148 if (instance_type == ASCII_STRING_TYPE) {
2149 return SeqAsciiString::SizeFor(
2150 reinterpret_cast<SeqAsciiString*>(this)->length());
2151 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002152 if (instance_type == BYTE_ARRAY_TYPE) {
2153 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2154 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002155 if (instance_type == STRING_TYPE) {
2156 return SeqTwoByteString::SizeFor(
2157 reinterpret_cast<SeqTwoByteString*>(this)->length());
2158 }
2159 ASSERT(instance_type == CODE_TYPE);
2160 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161}
2162
2163
2164void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002165 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002166 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167 ASSERT(0 <= value && value < 256);
2168 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2169}
2170
2171
ager@chromium.org7c537e22008-10-16 08:43:32 +00002172void Map::set_inobject_properties(int value) {
2173 ASSERT(0 <= value && value < 256);
2174 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2175}
2176
2177
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002178void Map::set_pre_allocated_property_fields(int value) {
2179 ASSERT(0 <= value && value < 256);
2180 WRITE_BYTE_FIELD(this,
2181 kPreAllocatedPropertyFieldsOffset,
2182 static_cast<byte>(value));
2183}
2184
2185
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186InstanceType Map::instance_type() {
2187 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2188}
2189
2190
2191void Map::set_instance_type(InstanceType value) {
2192 ASSERT(0 <= value && value < 256);
2193 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2194}
2195
2196
2197int Map::unused_property_fields() {
2198 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2199}
2200
2201
2202void Map::set_unused_property_fields(int value) {
2203 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2204}
2205
2206
2207byte Map::bit_field() {
2208 return READ_BYTE_FIELD(this, kBitFieldOffset);
2209}
2210
2211
2212void Map::set_bit_field(byte value) {
2213 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2214}
2215
2216
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002217byte Map::bit_field2() {
2218 return READ_BYTE_FIELD(this, kBitField2Offset);
2219}
2220
2221
2222void Map::set_bit_field2(byte value) {
2223 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2224}
2225
2226
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227void Map::set_non_instance_prototype(bool value) {
2228 if (value) {
2229 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2230 } else {
2231 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2232 }
2233}
2234
2235
2236bool Map::has_non_instance_prototype() {
2237 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2238}
2239
2240
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002241void Map::set_function_with_prototype(bool value) {
2242 if (value) {
2243 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2244 } else {
2245 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2246 }
2247}
2248
2249
2250bool Map::function_with_prototype() {
2251 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2252}
2253
2254
ager@chromium.org870a0b62008-11-04 11:43:05 +00002255void Map::set_is_access_check_needed(bool access_check_needed) {
2256 if (access_check_needed) {
2257 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2258 } else {
2259 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2260 }
2261}
2262
2263
2264bool Map::is_access_check_needed() {
2265 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2266}
2267
2268
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002269void Map::set_is_extensible(bool value) {
2270 if (value) {
2271 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2272 } else {
2273 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2274 }
2275}
2276
2277bool Map::is_extensible() {
2278 return ((1 << kIsExtensible) & bit_field2()) != 0;
2279}
2280
2281
2282
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002283Code::Flags Code::flags() {
2284 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2285}
2286
2287
2288void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002289 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002291 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2292 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002293 ExtractArgumentsCountFromFlags(flags) >= 0);
2294 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2295}
2296
2297
2298Code::Kind Code::kind() {
2299 return ExtractKindFromFlags(flags());
2300}
2301
2302
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002303InLoopFlag Code::ic_in_loop() {
2304 return ExtractICInLoopFromFlags(flags());
2305}
2306
2307
kasper.lund7276f142008-07-30 08:49:36 +00002308InlineCacheState Code::ic_state() {
2309 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002310 // Only allow uninitialized or debugger states for non-IC code
2311 // objects. This is used in the debugger to determine whether or not
2312 // a call to code object has been replaced with a debug break call.
2313 ASSERT(is_inline_cache_stub() ||
2314 result == UNINITIALIZED ||
2315 result == DEBUG_BREAK ||
2316 result == DEBUG_PREPARE_STEP_IN);
2317 return result;
2318}
2319
2320
2321PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002322 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002323 return ExtractTypeFromFlags(flags());
2324}
2325
2326
2327int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002328 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329 return ExtractArgumentsCountFromFlags(flags());
2330}
2331
2332
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002333int Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002334 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002335 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002336}
2337
2338
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002339void Code::set_major_key(int major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002340 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002341 ASSERT(0 <= major && major < 256);
2342 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343}
2344
2345
2346bool Code::is_inline_cache_stub() {
2347 Kind kind = this->kind();
2348 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2349}
2350
2351
2352Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002353 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002354 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002355 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002356 int argc,
2357 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358 // Compute the bit mask.
2359 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002360 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002361 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002362 bits |= type << kFlagsTypeShift;
2363 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002364 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365 // Cast to flags and validate result before returning it.
2366 Flags result = static_cast<Flags>(bits);
2367 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002368 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002369 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370 ASSERT(ExtractTypeFromFlags(result) == type);
2371 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2372 return result;
2373}
2374
2375
2376Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2377 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002378 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002379 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002381 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002382}
2383
2384
2385Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2386 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2387 return static_cast<Kind>(bits);
2388}
2389
2390
kasper.lund7276f142008-07-30 08:49:36 +00002391InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2392 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393 return static_cast<InlineCacheState>(bits);
2394}
2395
2396
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002397InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2398 int bits = (flags & kFlagsICInLoopMask);
2399 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2400}
2401
2402
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2404 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2405 return static_cast<PropertyType>(bits);
2406}
2407
2408
2409int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2410 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2411}
2412
2413
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002414InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2415 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2416 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2417}
2418
2419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2421 int bits = flags & ~kFlagsTypeMask;
2422 return static_cast<Flags>(bits);
2423}
2424
2425
ager@chromium.org8bb60582008-12-11 12:02:20 +00002426Code* Code::GetCodeFromTargetAddress(Address address) {
2427 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2428 // GetCodeFromTargetAddress might be called when marking objects during mark
2429 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2430 // Code::cast. Code::cast does not work when the object's map is
2431 // marked.
2432 Code* result = reinterpret_cast<Code*>(code);
2433 return result;
2434}
2435
2436
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002437Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2438 return HeapObject::
2439 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2440}
2441
2442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443Object* Map::prototype() {
2444 return READ_FIELD(this, kPrototypeOffset);
2445}
2446
2447
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002448void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002449 ASSERT(value->IsNull() || value->IsJSObject());
2450 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002451 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002452}
2453
2454
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002455Object* Map::GetFastElementsMap() {
2456 if (has_fast_elements()) return this;
2457 Object* obj = CopyDropTransitions();
2458 if (obj->IsFailure()) return obj;
2459 Map* new_map = Map::cast(obj);
2460 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002461 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002462 return new_map;
2463}
2464
2465
2466Object* Map::GetSlowElementsMap() {
2467 if (!has_fast_elements()) return this;
2468 Object* obj = CopyDropTransitions();
2469 if (obj->IsFailure()) return obj;
2470 Map* new_map = Map::cast(obj);
2471 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002472 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002473 return new_map;
2474}
2475
2476
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002477ACCESSORS(Map, instance_descriptors, DescriptorArray,
2478 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002479ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002480ACCESSORS(Map, constructor, Object, kConstructorOffset)
2481
2482ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2483ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2484
2485ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2486ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002487ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002488
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002489ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002490
2491ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2492ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2493ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2494ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2495ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002496ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497
2498ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2499ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2500ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2501
2502ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2503ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2504ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2505ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2506ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2507ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2508
2509ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2510ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2511
2512ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2513ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2514
2515ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2516ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2518 kPropertyAccessorsOffset)
2519ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2520 kPrototypeTemplateOffset)
2521ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2522ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2523 kNamedPropertyHandlerOffset)
2524ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2525 kIndexedPropertyHandlerOffset)
2526ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2527 kInstanceTemplateOffset)
2528ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2529ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002530ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2531 kInstanceCallHandlerOffset)
2532ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2533 kAccessCheckInfoOffset)
2534ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2535
2536ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002537ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2538 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539
2540ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2541ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2542
2543ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2544
2545ACCESSORS(Script, source, Object, kSourceOffset)
2546ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002547ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002548ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2549ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002550ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002551ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002552ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2553ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002554ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002555ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002556ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002557ACCESSORS(Script, eval_from_instructions_offset, Smi,
2558 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002559
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002560#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002561ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2562ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2563ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2564ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2565
2566ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2567ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2568ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2569ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002570#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002571
2572ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002573ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002574ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2575 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002576ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002577ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2578ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002579ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002580ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2581 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582
2583BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2584 kHiddenPrototypeBit)
2585BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2586BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2587 kNeedsAccessCheckBit)
2588BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2589 kIsExpressionBit)
2590BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2591 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002592BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002593 has_only_simple_this_property_assignments,
2594 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002595BOOL_ACCESSORS(SharedFunctionInfo,
2596 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002597 try_full_codegen,
2598 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002599BOOL_ACCESSORS(SharedFunctionInfo,
2600 compiler_hints,
2601 allows_lazy_compilation,
2602 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002604
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002605#if V8_HOST_ARCH_32_BIT
2606SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2607SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002609SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002611SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2612SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002613 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002614SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2615SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002616 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002617SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002618 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002619SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002620 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002621#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002622
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002623#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2624 int holder::name() { \
2625 int value = READ_INT_FIELD(this, offset); \
2626 ASSERT(kHeapObjectTag == 1); \
2627 ASSERT((value & kHeapObjectTag) == 0); \
2628 return value >> 1; \
2629 } \
2630 void holder::set_##name(int value) { \
2631 ASSERT(kHeapObjectTag == 1); \
2632 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2633 (value & 0xC0000000) == 0x000000000); \
2634 WRITE_INT_FIELD(this, \
2635 offset, \
2636 (value << 1) & ~kHeapObjectTag); \
2637 }
2638
2639#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2640 INT_ACCESSORS(holder, name, offset)
2641
2642
2643
2644PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2645PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2646 kFormalParameterCountOffset)
2647
2648PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2649 kExpectedNofPropertiesOffset)
2650PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2651
2652PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2653 kStartPositionAndTypeOffset)
2654PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2655
2656PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2657 kFunctionTokenPositionOffset)
2658PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2659 kCompilerHintsOffset)
2660
2661PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2662 kThisPropertyAssignmentsCountOffset)
2663#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002665ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2666ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2667
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002668bool Script::HasValidSource() {
2669 Object* src = this->source();
2670 if (!src->IsString()) return true;
2671 String* src_str = String::cast(src);
2672 if (!StringShape(src_str).IsExternal()) return true;
2673 if (src_str->IsAsciiRepresentation()) {
2674 return ExternalAsciiString::cast(src)->resource() != NULL;
2675 } else if (src_str->IsTwoByteRepresentation()) {
2676 return ExternalTwoByteString::cast(src)->resource() != NULL;
2677 }
2678 return true;
2679}
2680
2681
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002682void SharedFunctionInfo::DontAdaptArguments() {
2683 ASSERT(code()->kind() == Code::BUILTIN);
2684 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2685}
2686
2687
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002688int SharedFunctionInfo::start_position() {
2689 return start_position_and_type() >> kStartPositionShift;
2690}
2691
2692
2693void SharedFunctionInfo::set_start_position(int start_position) {
2694 set_start_position_and_type((start_position << kStartPositionShift)
2695 | (start_position_and_type() & ~kStartPositionMask));
2696}
2697
2698
2699Code* SharedFunctionInfo::code() {
2700 return Code::cast(READ_FIELD(this, kCodeOffset));
2701}
2702
2703
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002704Code* SharedFunctionInfo::unchecked_code() {
2705 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2706}
2707
2708
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002709void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002710 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002711 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712}
2713
2714
ager@chromium.orgb5737492010-07-15 09:29:43 +00002715SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2716 return reinterpret_cast<SerializedScopeInfo*>(
2717 READ_FIELD(this, kScopeInfoOffset));
2718}
2719
2720
2721void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2722 WriteBarrierMode mode) {
2723 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2724 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2725}
2726
2727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002729 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002730}
2731
2732
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002733bool SharedFunctionInfo::IsApiFunction() {
2734 return function_data()->IsFunctionTemplateInfo();
2735}
2736
2737
2738FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2739 ASSERT(IsApiFunction());
2740 return FunctionTemplateInfo::cast(function_data());
2741}
2742
2743
2744bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002745 return function_data()->IsSmi();
2746}
2747
2748
2749int SharedFunctionInfo::custom_call_generator_id() {
2750 ASSERT(HasCustomCallGenerator());
2751 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002752}
2753
2754
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002755int SharedFunctionInfo::code_age() {
2756 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2757}
2758
2759
2760void SharedFunctionInfo::set_code_age(int code_age) {
2761 set_compiler_hints(compiler_hints() |
2762 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2763}
2764
2765
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002766bool JSFunction::IsBuiltin() {
2767 return context()->global()->IsJSBuiltinsObject();
2768}
2769
2770
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002772 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002773}
2774
2775
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002776Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002777 return reinterpret_cast<Code*>(
2778 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002779}
2780
2781
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002783 // Skip the write barrier because code is never in new space.
2784 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002785 Address entry = value->entry();
2786 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787}
2788
2789
2790Context* JSFunction::context() {
2791 return Context::cast(READ_FIELD(this, kContextOffset));
2792}
2793
2794
2795Object* JSFunction::unchecked_context() {
2796 return READ_FIELD(this, kContextOffset);
2797}
2798
2799
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002800SharedFunctionInfo* JSFunction::unchecked_shared() {
2801 return reinterpret_cast<SharedFunctionInfo*>(
2802 READ_FIELD(this, kSharedFunctionInfoOffset));
2803}
2804
2805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002806void JSFunction::set_context(Object* value) {
2807 ASSERT(value == Heap::undefined_value() || value->IsContext());
2808 WRITE_FIELD(this, kContextOffset, value);
2809 WRITE_BARRIER(this, kContextOffset);
2810}
2811
2812ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2813 kPrototypeOrInitialMapOffset)
2814
2815
2816Map* JSFunction::initial_map() {
2817 return Map::cast(prototype_or_initial_map());
2818}
2819
2820
2821void JSFunction::set_initial_map(Map* value) {
2822 set_prototype_or_initial_map(value);
2823}
2824
2825
2826bool JSFunction::has_initial_map() {
2827 return prototype_or_initial_map()->IsMap();
2828}
2829
2830
2831bool JSFunction::has_instance_prototype() {
2832 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2833}
2834
2835
2836bool JSFunction::has_prototype() {
2837 return map()->has_non_instance_prototype() || has_instance_prototype();
2838}
2839
2840
2841Object* JSFunction::instance_prototype() {
2842 ASSERT(has_instance_prototype());
2843 if (has_initial_map()) return initial_map()->prototype();
2844 // When there is no initial map and the prototype is a JSObject, the
2845 // initial map field is used for the prototype field.
2846 return prototype_or_initial_map();
2847}
2848
2849
2850Object* JSFunction::prototype() {
2851 ASSERT(has_prototype());
2852 // If the function's prototype property has been set to a non-JSObject
2853 // value, that value is stored in the constructor field of the map.
2854 if (map()->has_non_instance_prototype()) return map()->constructor();
2855 return instance_prototype();
2856}
2857
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002858bool JSFunction::should_have_prototype() {
2859 return map()->function_with_prototype();
2860}
2861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002862
2863bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002864 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865}
2866
2867
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002868int JSFunction::NumberOfLiterals() {
2869 return literals()->length();
2870}
2871
2872
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002873Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2874 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002875 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876}
2877
2878
2879void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2880 Object* value) {
2881 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002882 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2883 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2884}
2885
2886
2887Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2888 ASSERT(0 <= id && id < kJSBuiltinsCount);
2889 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2890}
2891
2892
2893void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2894 Code* value) {
2895 ASSERT(0 <= id && id < kJSBuiltinsCount);
2896 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2897 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002898}
2899
2900
2901Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002902 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002903}
2904
2905
2906void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002907 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002908}
2909
2910
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911ACCESSORS(JSValue, value, Object, kValueOffset)
2912
2913
2914JSValue* JSValue::cast(Object* obj) {
2915 ASSERT(obj->IsJSValue());
2916 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2917 return reinterpret_cast<JSValue*>(obj);
2918}
2919
2920
2921INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002922ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002923
2924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002925byte* Code::instruction_start() {
2926 return FIELD_ADDR(this, kHeaderSize);
2927}
2928
2929
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002930byte* Code::instruction_end() {
2931 return instruction_start() + instruction_size();
2932}
2933
2934
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002935int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002936 return RoundUp(instruction_size(), kObjectAlignment);
2937}
2938
2939
2940ByteArray* Code::unchecked_relocation_info() {
2941 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942}
2943
2944
2945byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00002946 return unchecked_relocation_info()->GetDataStartAddress();
2947}
2948
2949
2950int Code::relocation_size() {
2951 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952}
2953
2954
2955byte* Code::entry() {
2956 return instruction_start();
2957}
2958
2959
2960bool Code::contains(byte* pc) {
2961 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00002962 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002963}
2964
2965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002966ACCESSORS(JSArray, length, Object, kLengthOffset)
2967
2968
ager@chromium.org236ad962008-09-25 09:45:57 +00002969ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002970
2971
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002972JSRegExp::Type JSRegExp::TypeTag() {
2973 Object* data = this->data();
2974 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2975 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2976 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002977}
2978
2979
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002980int JSRegExp::CaptureCount() {
2981 switch (TypeTag()) {
2982 case ATOM:
2983 return 0;
2984 case IRREGEXP:
2985 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2986 default:
2987 UNREACHABLE();
2988 return -1;
2989 }
2990}
2991
2992
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002993JSRegExp::Flags JSRegExp::GetFlags() {
2994 ASSERT(this->data()->IsFixedArray());
2995 Object* data = this->data();
2996 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2997 return Flags(smi->value());
2998}
2999
3000
3001String* JSRegExp::Pattern() {
3002 ASSERT(this->data()->IsFixedArray());
3003 Object* data = this->data();
3004 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3005 return pattern;
3006}
3007
3008
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003009Object* JSRegExp::DataAt(int index) {
3010 ASSERT(TypeTag() != NOT_COMPILED);
3011 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003012}
3013
3014
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003015void JSRegExp::SetDataAt(int index, Object* value) {
3016 ASSERT(TypeTag() != NOT_COMPILED);
3017 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3018 FixedArray::cast(data())->set(index, value);
3019}
3020
3021
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003022JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003023 if (map()->has_fast_elements()) {
3024 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3025 elements()->map() == Heap::fixed_cow_array_map());
3026 return FAST_ELEMENTS;
3027 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003028 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003029 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003030 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3031 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003032 ASSERT(array->IsDictionary());
3033 return DICTIONARY_ELEMENTS;
3034 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003035 if (array->IsExternalArray()) {
3036 switch (array->map()->instance_type()) {
3037 case EXTERNAL_BYTE_ARRAY_TYPE:
3038 return EXTERNAL_BYTE_ELEMENTS;
3039 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3040 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3041 case EXTERNAL_SHORT_ARRAY_TYPE:
3042 return EXTERNAL_SHORT_ELEMENTS;
3043 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3044 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3045 case EXTERNAL_INT_ARRAY_TYPE:
3046 return EXTERNAL_INT_ELEMENTS;
3047 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3048 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3049 default:
3050 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3051 return EXTERNAL_FLOAT_ELEMENTS;
3052 }
3053 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003054 ASSERT(array->IsPixelArray());
3055 return PIXEL_ELEMENTS;
3056}
3057
3058
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003060 return GetElementsKind() == FAST_ELEMENTS;
3061}
3062
3063
3064bool JSObject::HasDictionaryElements() {
3065 return GetElementsKind() == DICTIONARY_ELEMENTS;
3066}
3067
3068
3069bool JSObject::HasPixelElements() {
3070 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003071}
3072
3073
ager@chromium.org3811b432009-10-28 14:53:37 +00003074bool JSObject::HasExternalArrayElements() {
3075 return (HasExternalByteElements() ||
3076 HasExternalUnsignedByteElements() ||
3077 HasExternalShortElements() ||
3078 HasExternalUnsignedShortElements() ||
3079 HasExternalIntElements() ||
3080 HasExternalUnsignedIntElements() ||
3081 HasExternalFloatElements());
3082}
3083
3084
3085bool JSObject::HasExternalByteElements() {
3086 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3087}
3088
3089
3090bool JSObject::HasExternalUnsignedByteElements() {
3091 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3092}
3093
3094
3095bool JSObject::HasExternalShortElements() {
3096 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3097}
3098
3099
3100bool JSObject::HasExternalUnsignedShortElements() {
3101 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3102}
3103
3104
3105bool JSObject::HasExternalIntElements() {
3106 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3107}
3108
3109
3110bool JSObject::HasExternalUnsignedIntElements() {
3111 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3112}
3113
3114
3115bool JSObject::HasExternalFloatElements() {
3116 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3117}
3118
3119
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003120bool JSObject::HasNamedInterceptor() {
3121 return map()->has_named_interceptor();
3122}
3123
3124
3125bool JSObject::HasIndexedInterceptor() {
3126 return map()->has_indexed_interceptor();
3127}
3128
3129
ager@chromium.org5c838252010-02-19 08:53:10 +00003130bool JSObject::AllowsSetElementsLength() {
3131 bool result = elements()->IsFixedArray();
3132 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3133 return result;
3134}
3135
3136
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003137Object* JSObject::EnsureWritableFastElements() {
3138 ASSERT(HasFastElements());
3139 FixedArray* elems = FixedArray::cast(elements());
3140 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
3141 Object* writable_elems = Heap::CopyFixedArray(elems);
3142 if (writable_elems->IsFailure()) return writable_elems;
3143 FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
3144 set_elements(FixedArray::cast(writable_elems));
3145 Counters::cow_arrays_converted.Increment();
3146 return writable_elems;
3147}
3148
3149
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003150StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003151 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003152 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003153}
3154
3155
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003156NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003157 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003158 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003159}
3160
3161
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003162bool String::IsHashFieldComputed(uint32_t field) {
3163 return (field & kHashNotComputedMask) == 0;
3164}
3165
3166
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003167bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003168 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003169}
3170
3171
3172uint32_t String::Hash() {
3173 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003174 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003175 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003176 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003177 return ComputeAndSetHash();
3178}
3179
3180
ager@chromium.org7c537e22008-10-16 08:43:32 +00003181StringHasher::StringHasher(int length)
3182 : length_(length),
3183 raw_running_hash_(0),
3184 array_index_(0),
3185 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3186 is_first_char_(true),
3187 is_valid_(true) { }
3188
3189
3190bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003191 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003192}
3193
3194
3195void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003196 // Use the Jenkins one-at-a-time hash function to update the hash
3197 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003198 raw_running_hash_ += c;
3199 raw_running_hash_ += (raw_running_hash_ << 10);
3200 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003201 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003202 if (is_array_index_) {
3203 if (c < '0' || c > '9') {
3204 is_array_index_ = false;
3205 } else {
3206 int d = c - '0';
3207 if (is_first_char_) {
3208 is_first_char_ = false;
3209 if (c == '0' && length_ > 1) {
3210 is_array_index_ = false;
3211 return;
3212 }
3213 }
3214 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3215 is_array_index_ = false;
3216 } else {
3217 array_index_ = array_index_ * 10 + d;
3218 }
3219 }
3220 }
3221}
3222
3223
3224void StringHasher::AddCharacterNoIndex(uc32 c) {
3225 ASSERT(!is_array_index());
3226 raw_running_hash_ += c;
3227 raw_running_hash_ += (raw_running_hash_ << 10);
3228 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3229}
3230
3231
3232uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003233 // Get the calculated raw hash value and do some more bit ops to distribute
3234 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003235 uint32_t result = raw_running_hash_;
3236 result += (result << 3);
3237 result ^= (result >> 11);
3238 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003239 if (result == 0) {
3240 result = 27;
3241 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003242 return result;
3243}
3244
3245
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003246bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003247 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003248 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3249 return false;
3250 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251 return SlowAsArrayIndex(index);
3252}
3253
3254
3255Object* JSObject::GetPrototype() {
3256 return JSObject::cast(this)->map()->prototype();
3257}
3258
3259
3260PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3261 return GetPropertyAttributeWithReceiver(this, key);
3262}
3263
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003264// TODO(504): this may be useful in other places too where JSGlobalProxy
3265// is used.
3266Object* JSObject::BypassGlobalProxy() {
3267 if (IsJSGlobalProxy()) {
3268 Object* proto = GetPrototype();
3269 if (proto->IsNull()) return Heap::undefined_value();
3270 ASSERT(proto->IsJSGlobalObject());
3271 return proto;
3272 }
3273 return this;
3274}
3275
3276
3277bool JSObject::HasHiddenPropertiesObject() {
3278 ASSERT(!IsJSGlobalProxy());
3279 return GetPropertyAttributePostInterceptor(this,
3280 Heap::hidden_symbol(),
3281 false) != ABSENT;
3282}
3283
3284
3285Object* JSObject::GetHiddenPropertiesObject() {
3286 ASSERT(!IsJSGlobalProxy());
3287 PropertyAttributes attributes;
3288 return GetLocalPropertyPostInterceptor(this,
3289 Heap::hidden_symbol(),
3290 &attributes);
3291}
3292
3293
3294Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3295 ASSERT(!IsJSGlobalProxy());
3296 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3297 hidden_obj,
3298 DONT_ENUM);
3299}
3300
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003301
3302bool JSObject::HasElement(uint32_t index) {
3303 return HasElementWithReceiver(this, index);
3304}
3305
3306
3307bool AccessorInfo::all_can_read() {
3308 return BooleanBit::get(flag(), kAllCanReadBit);
3309}
3310
3311
3312void AccessorInfo::set_all_can_read(bool value) {
3313 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3314}
3315
3316
3317bool AccessorInfo::all_can_write() {
3318 return BooleanBit::get(flag(), kAllCanWriteBit);
3319}
3320
3321
3322void AccessorInfo::set_all_can_write(bool value) {
3323 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3324}
3325
3326
ager@chromium.org870a0b62008-11-04 11:43:05 +00003327bool AccessorInfo::prohibits_overwriting() {
3328 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3329}
3330
3331
3332void AccessorInfo::set_prohibits_overwriting(bool value) {
3333 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3334}
3335
3336
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003337PropertyAttributes AccessorInfo::property_attributes() {
3338 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3339}
3340
3341
3342void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3343 ASSERT(AttributesField::is_valid(attributes));
3344 int rest_value = flag()->value() & ~AttributesField::mask();
3345 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3346}
3347
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003348template<typename Shape, typename Key>
3349void Dictionary<Shape, Key>::SetEntry(int entry,
3350 Object* key,
3351 Object* value,
3352 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003353 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003354 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003355 AssertNoAllocation no_gc;
3356 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003357 FixedArray::set(index, key, mode);
3358 FixedArray::set(index+1, value, mode);
3359 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360}
3361
3362
3363void Map::ClearCodeCache() {
3364 // No write barrier is needed since empty_fixed_array is not in new space.
3365 // Please note this function is used during marking:
3366 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003367 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3368 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369}
3370
3371
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003372void JSArray::EnsureSize(int required_size) {
3373 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003374 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003375 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3376 if (elts->length() < required_size) {
3377 // Doubling in size would be overkill, but leave some slack to avoid
3378 // constantly growing.
3379 Expand(required_size + (required_size >> 3));
3380 // It's a performance benefit to keep a frequently used array in new-space.
3381 } else if (!Heap::new_space()->Contains(elts) &&
3382 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3383 // Expand will allocate a new backing store in new space even if the size
3384 // we asked for isn't larger than what we had before.
3385 Expand(required_size);
3386 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003387}
3388
3389
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003390void JSArray::set_length(Smi* length) {
3391 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3392}
3393
3394
ager@chromium.org7c537e22008-10-16 08:43:32 +00003395void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003396 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003397 set_elements(storage);
3398}
3399
3400
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003401Object* FixedArray::Copy() {
3402 if (length() == 0) return this;
3403 return Heap::CopyFixedArray(this);
3404}
3405
3406
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003407int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3408 return map->instance_size();
3409}
3410
3411
3412void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3413 v->VisitExternalReference(
3414 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3415}
3416
3417
3418template<typename StaticVisitor>
3419void Proxy::ProxyIterateBody() {
3420 StaticVisitor::VisitExternalReference(
3421 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3422}
3423
3424
3425void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3426 typedef v8::String::ExternalAsciiStringResource Resource;
3427 v->VisitExternalAsciiString(
3428 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3429}
3430
3431
3432template<typename StaticVisitor>
3433void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3434 typedef v8::String::ExternalAsciiStringResource Resource;
3435 StaticVisitor::VisitExternalAsciiString(
3436 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3437}
3438
3439
3440void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3441 typedef v8::String::ExternalStringResource Resource;
3442 v->VisitExternalTwoByteString(
3443 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3444}
3445
3446
3447template<typename StaticVisitor>
3448void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3449 typedef v8::String::ExternalStringResource Resource;
3450 StaticVisitor::VisitExternalTwoByteString(
3451 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3452}
3453
3454#define SLOT_ADDR(obj, offset) \
3455 reinterpret_cast<Object**>((obj)->address() + offset)
3456
3457template<int start_offset, int end_offset, int size>
3458void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3459 HeapObject* obj,
3460 ObjectVisitor* v) {
3461 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3462}
3463
3464
3465template<int start_offset>
3466void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3467 int object_size,
3468 ObjectVisitor* v) {
3469 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3470}
3471
3472#undef SLOT_ADDR
3473
3474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003475#undef CAST_ACCESSOR
3476#undef INT_ACCESSORS
3477#undef SMI_ACCESSORS
3478#undef ACCESSORS
3479#undef FIELD_ADDR
3480#undef READ_FIELD
3481#undef WRITE_FIELD
3482#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003483#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484#undef READ_MEMADDR_FIELD
3485#undef WRITE_MEMADDR_FIELD
3486#undef READ_DOUBLE_FIELD
3487#undef WRITE_DOUBLE_FIELD
3488#undef READ_INT_FIELD
3489#undef WRITE_INT_FIELD
3490#undef READ_SHORT_FIELD
3491#undef WRITE_SHORT_FIELD
3492#undef READ_BYTE_FIELD
3493#undef WRITE_BYTE_FIELD
3494
3495
3496} } // namespace v8::internal
3497
3498#endif // V8_OBJECTS_INL_H_