blob: e7daa2d68c87eea5a3202beaa905e21c162d8d67 [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
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000056PropertyDetails PropertyDetails::AsDeleted() {
57 PropertyDetails d(DONT_ENUM, NORMAL);
58 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
59 return PropertyDetails(smi);
60}
61
62
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 ASSERT(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 }
68
69
70#define INT_ACCESSORS(holder, name, offset) \
71 int holder::name() { return READ_INT_FIELD(this, offset); } \
72 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
73
74
75#define ACCESSORS(holder, name, type, offset) \
76 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000077 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 }
81
82
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084#define SMI_ACCESSORS(holder, name, offset) \
85 int holder::name() { \
86 Object* value = READ_FIELD(this, offset); \
87 return Smi::cast(value)->value(); \
88 } \
89 void holder::set_##name(int value) { \
90 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
91 }
92
93
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000094#define BOOL_GETTER(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98
99
100#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104 void holder::set_##name(bool value) { \
105 set_##field(BooleanBit::set(field(), offset, value)); \
106 }
107
108
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000109bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
110 // There is a constraint on the object; check.
111 if (!this->IsJSObject()) return false;
112 // Fetch the constructor function of the object.
113 Object* cons_obj = JSObject::cast(this)->map()->constructor();
114 if (!cons_obj->IsJSFunction()) return false;
115 JSFunction* fun = JSFunction::cast(cons_obj);
116 // Iterate through the chain of inheriting function templates to
117 // see if the required one occurs.
118 for (Object* type = fun->shared()->function_data();
119 type->IsFunctionTemplateInfo();
120 type = FunctionTemplateInfo::cast(type)->parent_template()) {
121 if (type == expected) return true;
122 }
123 // Didn't find the required type in the inheritance chain.
124 return false;
125}
126
127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128bool Object::IsSmi() {
129 return HAS_SMI_TAG(this);
130}
131
132
133bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000134 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135}
136
137
138bool Object::IsHeapNumber() {
139 return Object::IsHeapObject()
140 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
141}
142
143
144bool Object::IsString() {
145 return Object::IsHeapObject()
146 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
147}
148
149
ager@chromium.org870a0b62008-11-04 11:43:05 +0000150bool Object::IsSymbol() {
151 if (!this->IsHeapObject()) return false;
152 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000153 // Because the symbol tag is non-zero and no non-string types have the
154 // symbol bit set we can test for symbols with a very simple test
155 // operation.
156 ASSERT(kSymbolTag != 0);
157 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
158 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159}
160
161
162bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000163 if (!this->IsHeapObject()) return false;
164 uint32_t type = HeapObject::cast(this)->map()->instance_type();
165 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
166 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167}
168
169
ager@chromium.org870a0b62008-11-04 11:43:05 +0000170bool Object::IsSeqString() {
171 if (!IsString()) return false;
172 return StringShape(String::cast(this)).IsSequential();
173}
174
175
176bool Object::IsSeqAsciiString() {
177 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000178 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000179 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180}
181
182
183bool Object::IsSeqTwoByteString() {
184 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000185 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000186 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187}
188
189
190bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191 if (!IsString()) return false;
192 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000198 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000199 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200}
201
202
203bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000204 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000205 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000206 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207}
208
209
ager@chromium.org870a0b62008-11-04 11:43:05 +0000210StringShape::StringShape(String* str)
211 : type_(str->map()->instance_type()) {
212 set_valid();
213 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217StringShape::StringShape(Map* map)
218 : type_(map->instance_type()) {
219 set_valid();
220 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221}
222
223
ager@chromium.org870a0b62008-11-04 11:43:05 +0000224StringShape::StringShape(InstanceType t)
225 : type_(static_cast<uint32_t>(t)) {
226 set_valid();
227 ASSERT((type_ & kIsNotStringMask) == kStringTag);
228}
229
230
231bool StringShape::IsSymbol() {
232 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000233 ASSERT(kSymbolTag != 0);
234 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235}
236
237
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238bool String::IsAsciiRepresentation() {
239 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240 if ((type & kStringRepresentationMask) == kConsStringTag &&
241 ConsString::cast(this)->second()->length() == 0) {
242 return ConsString::cast(this)->first()->IsAsciiRepresentation();
243 }
244 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245}
246
247
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248bool String::IsTwoByteRepresentation() {
249 uint32_t type = map()->instance_type();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000250 if ((type & kStringRepresentationMask) == kConsStringTag &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 ConsString::cast(this)->second()->length() == 0) {
252 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
253 }
254 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000255}
256
257
258bool StringShape::IsCons() {
259 return (type_ & kStringRepresentationMask) == kConsStringTag;
260}
261
262
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263bool StringShape::IsExternal() {
264 return (type_ & kStringRepresentationMask) == kExternalStringTag;
265}
266
267
268bool StringShape::IsSequential() {
269 return (type_ & kStringRepresentationMask) == kSeqStringTag;
270}
271
272
273StringRepresentationTag StringShape::representation_tag() {
274 uint32_t tag = (type_ & kStringRepresentationMask);
275 return static_cast<StringRepresentationTag>(tag);
276}
277
278
279uint32_t StringShape::full_representation_tag() {
280 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
281}
282
283
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000284STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
285 Internals::kFullStringRepresentationMask);
286
287
ager@chromium.org870a0b62008-11-04 11:43:05 +0000288bool StringShape::IsSequentialAscii() {
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
290}
291
292
293bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
298bool StringShape::IsExternalAscii() {
299 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305}
306
307
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000308STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
309 Internals::kExternalTwoByteRepresentationTag);
310
311
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312uc32 FlatStringReader::Get(int index) {
313 ASSERT(0 <= index && index <= length_);
314 if (is_ascii_) {
315 return static_cast<const byte*>(start_)[index];
316 } else {
317 return static_cast<const uc16*>(start_)[index];
318 }
319}
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322bool Object::IsNumber() {
323 return IsSmi() || IsHeapNumber();
324}
325
326
327bool Object::IsByteArray() {
328 return Object::IsHeapObject()
329 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
330}
331
332
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000333bool Object::IsPixelArray() {
334 return Object::IsHeapObject() &&
335 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
336}
337
338
ager@chromium.org3811b432009-10-28 14:53:37 +0000339bool Object::IsExternalArray() {
340 if (!Object::IsHeapObject())
341 return false;
342 InstanceType instance_type =
343 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000344 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
345 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000346}
347
348
349bool Object::IsExternalByteArray() {
350 return Object::IsHeapObject() &&
351 HeapObject::cast(this)->map()->instance_type() ==
352 EXTERNAL_BYTE_ARRAY_TYPE;
353}
354
355
356bool Object::IsExternalUnsignedByteArray() {
357 return Object::IsHeapObject() &&
358 HeapObject::cast(this)->map()->instance_type() ==
359 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
360}
361
362
363bool Object::IsExternalShortArray() {
364 return Object::IsHeapObject() &&
365 HeapObject::cast(this)->map()->instance_type() ==
366 EXTERNAL_SHORT_ARRAY_TYPE;
367}
368
369
370bool Object::IsExternalUnsignedShortArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalIntArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_INT_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalUnsignedIntArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalFloatArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_FLOAT_ARRAY_TYPE;
395}
396
397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398bool Object::IsFailure() {
399 return HAS_FAILURE_TAG(this);
400}
401
402
403bool Object::IsRetryAfterGC() {
404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
ager@chromium.org7c537e22008-10-16 08:43:32 +0000409bool Object::IsOutOfMemoryFailure() {
410 return HAS_FAILURE_TAG(this)
411 && Failure::cast(this)->IsOutOfMemoryException();
412}
413
414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415bool Object::IsException() {
416 return this == Failure::Exception();
417}
418
419
420bool Object::IsJSObject() {
421 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000422 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423}
424
425
ager@chromium.org32912102009-01-16 10:38:43 +0000426bool Object::IsJSContextExtensionObject() {
427 return IsHeapObject()
428 && (HeapObject::cast(this)->map()->instance_type() ==
429 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
430}
431
432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433bool Object::IsMap() {
434 return Object::IsHeapObject()
435 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
436}
437
438
439bool Object::IsFixedArray() {
440 return Object::IsHeapObject()
441 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
442}
443
444
445bool Object::IsDescriptorArray() {
446 return IsFixedArray();
447}
448
449
450bool Object::IsContext() {
451 return Object::IsHeapObject()
452 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000453 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 HeapObject::cast(this)->map() == Heap::global_context_map());
455}
456
457
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000458bool Object::IsCatchContext() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::catch_context_map();
461}
462
463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464bool Object::IsGlobalContext() {
465 return Object::IsHeapObject()
466 && HeapObject::cast(this)->map() == Heap::global_context_map();
467}
468
469
470bool Object::IsJSFunction() {
471 return Object::IsHeapObject()
472 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
473}
474
475
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000476template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 return obj->IsJSFunction();
478}
479
480
481bool Object::IsCode() {
482 return Object::IsHeapObject()
483 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
484}
485
486
487bool Object::IsOddball() {
488 return Object::IsHeapObject()
489 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
490}
491
492
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000493bool Object::IsJSGlobalPropertyCell() {
494 return Object::IsHeapObject()
495 && HeapObject::cast(this)->map()->instance_type()
496 == JS_GLOBAL_PROPERTY_CELL_TYPE;
497}
498
499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500bool Object::IsSharedFunctionInfo() {
501 return Object::IsHeapObject() &&
502 (HeapObject::cast(this)->map()->instance_type() ==
503 SHARED_FUNCTION_INFO_TYPE);
504}
505
506
507bool Object::IsJSValue() {
508 return Object::IsHeapObject()
509 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
510}
511
512
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000513bool Object::IsStringWrapper() {
514 return IsJSValue() && JSValue::cast(this)->value()->IsString();
515}
516
517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518bool Object::IsProxy() {
519 return Object::IsHeapObject()
520 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
521}
522
523
524bool Object::IsBoolean() {
525 return IsTrue() || IsFalse();
526}
527
528
529bool Object::IsJSArray() {
530 return Object::IsHeapObject()
531 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
532}
533
534
ager@chromium.org236ad962008-09-25 09:45:57 +0000535bool Object::IsJSRegExp() {
536 return Object::IsHeapObject()
537 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
538}
539
540
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000541template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 return obj->IsJSArray();
543}
544
545
546bool Object::IsHashTable() {
547 return Object::IsHeapObject()
548 && HeapObject::cast(this)->map() == Heap::hash_table_map();
549}
550
551
552bool Object::IsDictionary() {
553 return IsHashTable() && this != Heap::symbol_table();
554}
555
556
557bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000558 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000562bool Object::IsCompilationCacheTable() {
563 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000564}
565
566
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000567bool Object::IsCodeCacheHashTable() {
568 return IsHashTable();
569}
570
571
ager@chromium.org236ad962008-09-25 09:45:57 +0000572bool Object::IsMapCache() {
573 return IsHashTable();
574}
575
576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577bool Object::IsPrimitive() {
578 return IsOddball() || IsNumber() || IsString();
579}
580
581
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000582bool Object::IsJSGlobalProxy() {
583 bool result = IsHeapObject() &&
584 (HeapObject::cast(this)->map()->instance_type() ==
585 JS_GLOBAL_PROXY_TYPE);
586 ASSERT(!result || IsAccessCheckNeeded());
587 return result;
588}
589
590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000592 if (!IsHeapObject()) return false;
593
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000594 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000595 return type == JS_GLOBAL_OBJECT_TYPE ||
596 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000597}
598
599
600bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601 return IsHeapObject() &&
602 (HeapObject::cast(this)->map()->instance_type() ==
603 JS_GLOBAL_OBJECT_TYPE);
604}
605
606
607bool Object::IsJSBuiltinsObject() {
608 return IsHeapObject() &&
609 (HeapObject::cast(this)->map()->instance_type() ==
610 JS_BUILTINS_OBJECT_TYPE);
611}
612
613
614bool Object::IsUndetectableObject() {
615 return IsHeapObject()
616 && HeapObject::cast(this)->map()->is_undetectable();
617}
618
619
620bool Object::IsAccessCheckNeeded() {
621 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000622 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
626bool Object::IsStruct() {
627 if (!IsHeapObject()) return false;
628 switch (HeapObject::cast(this)->map()->instance_type()) {
629#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
630 STRUCT_LIST(MAKE_STRUCT_CASE)
631#undef MAKE_STRUCT_CASE
632 default: return false;
633 }
634}
635
636
637#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
638 bool Object::Is##Name() { \
639 return Object::IsHeapObject() \
640 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
641 }
642 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
643#undef MAKE_STRUCT_PREDICATE
644
645
646bool Object::IsUndefined() {
647 return this == Heap::undefined_value();
648}
649
650
651bool Object::IsTheHole() {
652 return this == Heap::the_hole_value();
653}
654
655
656bool Object::IsNull() {
657 return this == Heap::null_value();
658}
659
660
661bool Object::IsTrue() {
662 return this == Heap::true_value();
663}
664
665
666bool Object::IsFalse() {
667 return this == Heap::false_value();
668}
669
670
671double Object::Number() {
672 ASSERT(IsNumber());
673 return IsSmi()
674 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
675 : reinterpret_cast<HeapNumber*>(this)->value();
676}
677
678
679
680Object* Object::ToSmi() {
681 if (IsSmi()) return this;
682 if (IsHeapNumber()) {
683 double value = HeapNumber::cast(this)->value();
684 int int_value = FastD2I(value);
685 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
686 return Smi::FromInt(int_value);
687 }
688 }
689 return Failure::Exception();
690}
691
692
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000693bool Object::HasSpecificClassOf(String* name) {
694 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698Object* Object::GetElement(uint32_t index) {
699 return GetElementWithReceiver(this, index);
700}
701
702
703Object* Object::GetProperty(String* key) {
704 PropertyAttributes attributes;
705 return GetPropertyWithReceiver(this, key, &attributes);
706}
707
708
709Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
710 return GetPropertyWithReceiver(this, key, attributes);
711}
712
713
714#define FIELD_ADDR(p, offset) \
715 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
716
717#define READ_FIELD(p, offset) \
718 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
719
720#define WRITE_FIELD(p, offset, value) \
721 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
722
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724#define WRITE_BARRIER(object, offset) \
725 Heap::RecordWrite(object->address(), offset);
726
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000727// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728// write due to the assert validating the written value.
729#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
730 if (mode == UPDATE_WRITE_BARRIER) { \
731 Heap::RecordWrite(object->address(), offset); \
732 } else { \
733 ASSERT(mode == SKIP_WRITE_BARRIER); \
734 ASSERT(Heap::InNewSpace(object) || \
735 !Heap::InNewSpace(READ_FIELD(object, offset))); \
736 }
737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738#define READ_DOUBLE_FIELD(p, offset) \
739 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
740
741#define WRITE_DOUBLE_FIELD(p, offset, value) \
742 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
743
744#define READ_INT_FIELD(p, offset) \
745 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
746
747#define WRITE_INT_FIELD(p, offset, value) \
748 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
749
ager@chromium.org3e875802009-06-29 08:26:34 +0000750#define READ_INTPTR_FIELD(p, offset) \
751 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
752
753#define WRITE_INTPTR_FIELD(p, offset, value) \
754 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
755
ager@chromium.org7c537e22008-10-16 08:43:32 +0000756#define READ_UINT32_FIELD(p, offset) \
757 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
758
759#define WRITE_UINT32_FIELD(p, offset, value) \
760 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
761
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000762#define READ_SHORT_FIELD(p, offset) \
763 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
764
765#define WRITE_SHORT_FIELD(p, offset, value) \
766 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
767
768#define READ_BYTE_FIELD(p, offset) \
769 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
770
771#define WRITE_BYTE_FIELD(p, offset, value) \
772 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
773
774
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000775Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
776 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000781 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785Smi* Smi::FromInt(int value) {
786 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000787 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000788 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000789 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000790 return reinterpret_cast<Smi*>(tagged_value);
791}
792
793
794Smi* Smi::FromIntptr(intptr_t value) {
795 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000796 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
797 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000798}
799
800
801Failure::Type Failure::type() const {
802 return static_cast<Type>(value() & kFailureTypeTagMask);
803}
804
805
806bool Failure::IsInternalError() const {
807 return type() == INTERNAL_ERROR;
808}
809
810
811bool Failure::IsOutOfMemoryException() const {
812 return type() == OUT_OF_MEMORY_EXCEPTION;
813}
814
815
816int Failure::requested() const {
817 const int kShiftBits =
818 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
819 STATIC_ASSERT(kShiftBits >= 0);
820 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000821 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822}
823
824
825AllocationSpace Failure::allocation_space() const {
826 ASSERT_EQ(RETRY_AFTER_GC, type());
827 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
828 & kSpaceTagMask);
829}
830
831
832Failure* Failure::InternalError() {
833 return Construct(INTERNAL_ERROR);
834}
835
836
837Failure* Failure::Exception() {
838 return Construct(EXCEPTION);
839}
840
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842Failure* Failure::OutOfMemoryException() {
843 return Construct(OUT_OF_MEMORY_EXCEPTION);
844}
845
846
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000847intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000848 return static_cast<intptr_t>(
849 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850}
851
852
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000853Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000854 // Assert that the space encoding fits in the three bytes allotted for it.
855 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000856 uintptr_t requested =
857 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
858 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000859 if (((requested << tag_bits) >> tag_bits) != requested) {
860 // No room for entire requested size in the bits. Round down to
861 // maximally representable size.
862 requested = static_cast<intptr_t>(
863 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
864 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000865 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000866 return Construct(RETRY_AFTER_GC, value);
867}
868
869
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000870Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000871 uintptr_t info =
872 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000873 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875}
876
877
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000878bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879#ifdef DEBUG
880 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
881#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000882
883#ifdef V8_TARGET_ARCH_X64
884 // To be representable as a long smi, the value must be a 32-bit integer.
885 bool result = (value == static_cast<int32_t>(value));
886#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887 // To be representable as an tagged small integer, the two
888 // most-significant bits of 'value' must be either 00 or 11 due to
889 // sign-extension. To check this we add 01 to the two
890 // most-significant bits, and check if the most-significant bit is 0
891 //
892 // CAUTION: The original code below:
893 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
894 // may lead to incorrect results according to the C language spec, and
895 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
896 // compiler may produce undefined results in case of signed integer
897 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000899#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000900 ASSERT(result == in_range);
901 return result;
902}
903
904
kasper.lund7276f142008-07-30 08:49:36 +0000905MapWord MapWord::FromMap(Map* map) {
906 return MapWord(reinterpret_cast<uintptr_t>(map));
907}
908
909
910Map* MapWord::ToMap() {
911 return reinterpret_cast<Map*>(value_);
912}
913
914
915bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000917}
918
919
920MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000921 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
922 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000923}
924
925
926HeapObject* MapWord::ToForwardingAddress() {
927 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000928 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000929}
930
931
932bool MapWord::IsMarked() {
933 return (value_ & kMarkingMask) == 0;
934}
935
936
937void MapWord::SetMark() {
938 value_ &= ~kMarkingMask;
939}
940
941
942void MapWord::ClearMark() {
943 value_ |= kMarkingMask;
944}
945
946
947bool MapWord::IsOverflowed() {
948 return (value_ & kOverflowMask) != 0;
949}
950
951
952void MapWord::SetOverflow() {
953 value_ |= kOverflowMask;
954}
955
956
957void MapWord::ClearOverflow() {
958 value_ &= ~kOverflowMask;
959}
960
961
962MapWord MapWord::EncodeAddress(Address map_address, int offset) {
963 // Offset is the distance in live bytes from the first live object in the
964 // same page. The offset between two objects in the same page should not
965 // exceed the object area size of a page.
966 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
967
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000968 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000969 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
970
971 Page* map_page = Page::FromAddress(map_address);
972 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
973
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000974 uintptr_t map_page_offset =
975 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000976
977 uintptr_t encoding =
978 (compact_offset << kForwardingOffsetShift) |
979 (map_page_offset << kMapPageOffsetShift) |
980 (map_page->mc_page_index << kMapPageIndexShift);
981 return MapWord(encoding);
982}
983
984
985Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000986 int map_page_index =
987 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +0000988 ASSERT_MAP_PAGE_INDEX(map_page_index);
989
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000990 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000991 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
992 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +0000993
994 return (map_space->PageAddress(map_page_index) + map_page_offset);
995}
996
997
998int MapWord::DecodeOffset() {
999 // The offset field is represented in the kForwardingOffsetBits
1000 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001001 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1002 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1003 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001004}
1005
1006
1007MapWord MapWord::FromEncodedAddress(Address address) {
1008 return MapWord(reinterpret_cast<uintptr_t>(address));
1009}
1010
1011
1012Address MapWord::ToEncodedAddress() {
1013 return reinterpret_cast<Address>(value_);
1014}
1015
1016
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001017#ifdef DEBUG
1018void HeapObject::VerifyObjectField(int offset) {
1019 VerifyPointer(READ_FIELD(this, offset));
1020}
1021#endif
1022
1023
1024Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001025 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026}
1027
1028
1029void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001030 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001031}
1032
1033
kasper.lund7276f142008-07-30 08:49:36 +00001034MapWord HeapObject::map_word() {
1035 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1036}
1037
1038
1039void HeapObject::set_map_word(MapWord map_word) {
1040 // WRITE_FIELD does not update the remembered set, but there is no need
1041 // here.
1042 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1043}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044
1045
1046HeapObject* HeapObject::FromAddress(Address address) {
1047 ASSERT_TAG_ALIGNED(address);
1048 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1049}
1050
1051
1052Address HeapObject::address() {
1053 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1054}
1055
1056
1057int HeapObject::Size() {
1058 return SizeFromMap(map());
1059}
1060
1061
1062void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1063 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1064 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1065}
1066
1067
1068void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1069 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1070}
1071
1072
kasper.lund7276f142008-07-30 08:49:36 +00001073bool HeapObject::IsMarked() {
1074 return map_word().IsMarked();
1075}
1076
1077
1078void HeapObject::SetMark() {
1079 ASSERT(!IsMarked());
1080 MapWord first_word = map_word();
1081 first_word.SetMark();
1082 set_map_word(first_word);
1083}
1084
1085
1086void HeapObject::ClearMark() {
1087 ASSERT(IsMarked());
1088 MapWord first_word = map_word();
1089 first_word.ClearMark();
1090 set_map_word(first_word);
1091}
1092
1093
1094bool HeapObject::IsOverflowed() {
1095 return map_word().IsOverflowed();
1096}
1097
1098
1099void HeapObject::SetOverflow() {
1100 MapWord first_word = map_word();
1101 first_word.SetOverflow();
1102 set_map_word(first_word);
1103}
1104
1105
1106void HeapObject::ClearOverflow() {
1107 ASSERT(IsOverflowed());
1108 MapWord first_word = map_word();
1109 first_word.ClearOverflow();
1110 set_map_word(first_word);
1111}
1112
1113
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114double HeapNumber::value() {
1115 return READ_DOUBLE_FIELD(this, kValueOffset);
1116}
1117
1118
1119void HeapNumber::set_value(double value) {
1120 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1121}
1122
1123
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001124int HeapNumber::get_exponent() {
1125 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1126 kExponentShift) - kExponentBias;
1127}
1128
1129
1130int HeapNumber::get_sign() {
1131 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1132}
1133
1134
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001135ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001136
1137
1138Array* JSObject::elements() {
1139 Object* array = READ_FIELD(this, kElementsOffset);
1140 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001141 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1142 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001143 return reinterpret_cast<Array*>(array);
1144}
1145
1146
1147void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1148 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001149 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1150 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001151 WRITE_FIELD(this, kElementsOffset, value);
1152 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1153}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154
1155
1156void JSObject::initialize_properties() {
1157 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1158 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1159}
1160
1161
1162void JSObject::initialize_elements() {
1163 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1164 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1165}
1166
1167
1168ACCESSORS(Oddball, to_string, String, kToStringOffset)
1169ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1170
1171
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001172Object* JSGlobalPropertyCell::value() {
1173 return READ_FIELD(this, kValueOffset);
1174}
1175
1176
1177void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1178 // The write barrier is not used for global property cells.
1179 ASSERT(!val->IsJSGlobalPropertyCell());
1180 WRITE_FIELD(this, kValueOffset, val);
1181}
1182
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001183
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001184int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001185 InstanceType type = map()->instance_type();
1186 // Check for the most common kind of JavaScript object before
1187 // falling into the generic switch. This speeds up the internal
1188 // field operations considerably on average.
1189 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1190 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001191 case JS_GLOBAL_PROXY_TYPE:
1192 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193 case JS_GLOBAL_OBJECT_TYPE:
1194 return JSGlobalObject::kSize;
1195 case JS_BUILTINS_OBJECT_TYPE:
1196 return JSBuiltinsObject::kSize;
1197 case JS_FUNCTION_TYPE:
1198 return JSFunction::kSize;
1199 case JS_VALUE_TYPE:
1200 return JSValue::kSize;
1201 case JS_ARRAY_TYPE:
1202 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001203 case JS_REGEXP_TYPE:
1204 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001205 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001206 return JSObject::kHeaderSize;
1207 default:
1208 UNREACHABLE();
1209 return 0;
1210 }
1211}
1212
1213
1214int JSObject::GetInternalFieldCount() {
1215 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001216 // Make sure to adjust for the number of in-object properties. These
1217 // properties do contribute to the size, but are not internal fields.
1218 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1219 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220}
1221
1222
1223Object* JSObject::GetInternalField(int index) {
1224 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001225 // Internal objects do follow immediately after the header, whereas in-object
1226 // properties are at the end of the object. Therefore there is no need
1227 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001228 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1229}
1230
1231
1232void JSObject::SetInternalField(int index, Object* value) {
1233 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001234 // Internal objects do follow immediately after the header, whereas in-object
1235 // properties are at the end of the object. Therefore there is no need
1236 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237 int offset = GetHeaderSize() + (kPointerSize * index);
1238 WRITE_FIELD(this, offset, value);
1239 WRITE_BARRIER(this, offset);
1240}
1241
1242
ager@chromium.org7c537e22008-10-16 08:43:32 +00001243// Access fast-case object properties at index. The use of these routines
1244// is needed to correctly distinguish between properties stored in-object and
1245// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001246Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001247 // Adjust for the number of properties stored in the object.
1248 index -= map()->inobject_properties();
1249 if (index < 0) {
1250 int offset = map()->instance_size() + (index * kPointerSize);
1251 return READ_FIELD(this, offset);
1252 } else {
1253 ASSERT(index < properties()->length());
1254 return properties()->get(index);
1255 }
1256}
1257
1258
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001259Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001260 // Adjust for the number of properties stored in the object.
1261 index -= map()->inobject_properties();
1262 if (index < 0) {
1263 int offset = map()->instance_size() + (index * kPointerSize);
1264 WRITE_FIELD(this, offset, value);
1265 WRITE_BARRIER(this, offset);
1266 } else {
1267 ASSERT(index < properties()->length());
1268 properties()->set(index, value);
1269 }
1270 return value;
1271}
1272
1273
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001274Object* JSObject::InObjectPropertyAt(int index) {
1275 // Adjust for the number of properties stored in the object.
1276 index -= map()->inobject_properties();
1277 ASSERT(index < 0);
1278 int offset = map()->instance_size() + (index * kPointerSize);
1279 return READ_FIELD(this, offset);
1280}
1281
1282
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001283Object* JSObject::InObjectPropertyAtPut(int index,
1284 Object* value,
1285 WriteBarrierMode mode) {
1286 // Adjust for the number of properties stored in the object.
1287 index -= map()->inobject_properties();
1288 ASSERT(index < 0);
1289 int offset = map()->instance_size() + (index * kPointerSize);
1290 WRITE_FIELD(this, offset, value);
1291 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1292 return value;
1293}
1294
1295
1296
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001298 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001299 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001300 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301 }
1302}
1303
1304
1305void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001306 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001307 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001308 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309 }
1310}
1311
1312
1313bool JSObject::HasFastProperties() {
1314 return !properties()->IsDictionary();
1315}
1316
1317
1318bool Array::IndexFromObject(Object* object, uint32_t* index) {
1319 if (object->IsSmi()) {
1320 int value = Smi::cast(object)->value();
1321 if (value < 0) return false;
1322 *index = value;
1323 return true;
1324 }
1325 if (object->IsHeapNumber()) {
1326 double value = HeapNumber::cast(object)->value();
1327 uint32_t uint_value = static_cast<uint32_t>(value);
1328 if (value == static_cast<double>(uint_value)) {
1329 *index = uint_value;
1330 return true;
1331 }
1332 }
1333 return false;
1334}
1335
1336
1337bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1338 if (!this->IsJSValue()) return false;
1339
1340 JSValue* js_value = JSValue::cast(this);
1341 if (!js_value->value()->IsString()) return false;
1342
1343 String* str = String::cast(js_value->value());
1344 if (index >= (uint32_t)str->length()) return false;
1345
1346 return true;
1347}
1348
1349
1350Object* FixedArray::get(int index) {
1351 ASSERT(index >= 0 && index < this->length());
1352 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1353}
1354
1355
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001356void FixedArray::set(int index, Smi* value) {
1357 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1358 int offset = kHeaderSize + index * kPointerSize;
1359 WRITE_FIELD(this, offset, value);
1360}
1361
1362
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001363void FixedArray::set(int index, Object* value) {
1364 ASSERT(index >= 0 && index < this->length());
1365 int offset = kHeaderSize + index * kPointerSize;
1366 WRITE_FIELD(this, offset, value);
1367 WRITE_BARRIER(this, offset);
1368}
1369
1370
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001371WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1373 return UPDATE_WRITE_BARRIER;
1374}
1375
1376
1377void FixedArray::set(int index,
1378 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001379 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 ASSERT(index >= 0 && index < this->length());
1381 int offset = kHeaderSize + index * kPointerSize;
1382 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384}
1385
1386
1387void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1388 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001389 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001390 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1391}
1392
1393
1394void FixedArray::set_undefined(int index) {
1395 ASSERT(index >= 0 && index < this->length());
1396 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1397 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1398 Heap::undefined_value());
1399}
1400
1401
ager@chromium.org236ad962008-09-25 09:45:57 +00001402void FixedArray::set_null(int index) {
1403 ASSERT(index >= 0 && index < this->length());
1404 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1405 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1406}
1407
1408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409void FixedArray::set_the_hole(int index) {
1410 ASSERT(index >= 0 && index < this->length());
1411 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1412 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1413}
1414
1415
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001416Object** FixedArray::data_start() {
1417 return HeapObject::RawField(this, kHeaderSize);
1418}
1419
1420
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001421bool DescriptorArray::IsEmpty() {
1422 ASSERT(this == Heap::empty_descriptor_array() ||
1423 this->length() > 2);
1424 return this == Heap::empty_descriptor_array();
1425}
1426
1427
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001428void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1429 Object* tmp = array->get(first);
1430 fast_set(array, first, array->get(second));
1431 fast_set(array, second, tmp);
1432}
1433
1434
1435int DescriptorArray::Search(String* name) {
1436 SLOW_ASSERT(IsSortedNoDuplicates());
1437
1438 // Check for empty descriptor array.
1439 int nof = number_of_descriptors();
1440 if (nof == 0) return kNotFound;
1441
1442 // Fast case: do linear search for small arrays.
1443 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001444 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001445 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446 }
1447
1448 // Slow case: perform binary search.
1449 return BinarySearch(name, 0, nof - 1);
1450}
1451
1452
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453String* DescriptorArray::GetKey(int descriptor_number) {
1454 ASSERT(descriptor_number < number_of_descriptors());
1455 return String::cast(get(ToKeyIndex(descriptor_number)));
1456}
1457
1458
1459Object* DescriptorArray::GetValue(int descriptor_number) {
1460 ASSERT(descriptor_number < number_of_descriptors());
1461 return GetContentArray()->get(ToValueIndex(descriptor_number));
1462}
1463
1464
1465Smi* DescriptorArray::GetDetails(int descriptor_number) {
1466 ASSERT(descriptor_number < number_of_descriptors());
1467 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1468}
1469
1470
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001471PropertyType DescriptorArray::GetType(int descriptor_number) {
1472 ASSERT(descriptor_number < number_of_descriptors());
1473 return PropertyDetails(GetDetails(descriptor_number)).type();
1474}
1475
1476
1477int DescriptorArray::GetFieldIndex(int descriptor_number) {
1478 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1479}
1480
1481
1482JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1483 return JSFunction::cast(GetValue(descriptor_number));
1484}
1485
1486
1487Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1488 ASSERT(GetType(descriptor_number) == CALLBACKS);
1489 return GetValue(descriptor_number);
1490}
1491
1492
1493AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1494 ASSERT(GetType(descriptor_number) == CALLBACKS);
1495 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1496 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1497}
1498
1499
1500bool DescriptorArray::IsProperty(int descriptor_number) {
1501 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1502}
1503
1504
1505bool DescriptorArray::IsTransition(int descriptor_number) {
1506 PropertyType t = GetType(descriptor_number);
1507 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1508}
1509
1510
1511bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1512 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1513}
1514
1515
1516bool DescriptorArray::IsDontEnum(int descriptor_number) {
1517 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1518}
1519
1520
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1522 desc->Init(GetKey(descriptor_number),
1523 GetValue(descriptor_number),
1524 GetDetails(descriptor_number));
1525}
1526
1527
1528void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1529 // Range check.
1530 ASSERT(descriptor_number < number_of_descriptors());
1531
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001532 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001533 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1534 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1535
1536 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1537 FixedArray* content_array = GetContentArray();
1538 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1539 fast_set(content_array, ToDetailsIndex(descriptor_number),
1540 desc->GetDetails().AsSmi());
1541}
1542
1543
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001544void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1545 Descriptor desc;
1546 src->Get(src_index, &desc);
1547 Set(index, &desc);
1548}
1549
1550
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001551void DescriptorArray::Swap(int first, int second) {
1552 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1553 FixedArray* content_array = GetContentArray();
1554 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1555 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1556}
1557
1558
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001559bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001560 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561 if (!max_index_object->IsSmi()) return false;
1562 return 0 !=
1563 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1564}
1565
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001566uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001568 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569 if (!max_index_object->IsSmi()) return 0;
1570 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1571 return value >> kRequiresSlowElementsTagSize;
1572}
1573
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001574void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001575 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001576}
1577
1578
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579// ------------------------------------
1580// Cast operations
1581
1582
1583CAST_ACCESSOR(FixedArray)
1584CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001586CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001587CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001588CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589CAST_ACCESSOR(String)
1590CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001591CAST_ACCESSOR(SeqAsciiString)
1592CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594CAST_ACCESSOR(ExternalString)
1595CAST_ACCESSOR(ExternalAsciiString)
1596CAST_ACCESSOR(ExternalTwoByteString)
1597CAST_ACCESSOR(JSObject)
1598CAST_ACCESSOR(Smi)
1599CAST_ACCESSOR(Failure)
1600CAST_ACCESSOR(HeapObject)
1601CAST_ACCESSOR(HeapNumber)
1602CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001603CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604CAST_ACCESSOR(SharedFunctionInfo)
1605CAST_ACCESSOR(Map)
1606CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001607CAST_ACCESSOR(GlobalObject)
1608CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609CAST_ACCESSOR(JSGlobalObject)
1610CAST_ACCESSOR(JSBuiltinsObject)
1611CAST_ACCESSOR(Code)
1612CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001613CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614CAST_ACCESSOR(Proxy)
1615CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001616CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001617CAST_ACCESSOR(ExternalArray)
1618CAST_ACCESSOR(ExternalByteArray)
1619CAST_ACCESSOR(ExternalUnsignedByteArray)
1620CAST_ACCESSOR(ExternalShortArray)
1621CAST_ACCESSOR(ExternalUnsignedShortArray)
1622CAST_ACCESSOR(ExternalIntArray)
1623CAST_ACCESSOR(ExternalUnsignedIntArray)
1624CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625CAST_ACCESSOR(Struct)
1626
1627
1628#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1629 STRUCT_LIST(MAKE_STRUCT_CAST)
1630#undef MAKE_STRUCT_CAST
1631
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001632
1633template <typename Shape, typename Key>
1634HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635 ASSERT(obj->IsHashTable());
1636 return reinterpret_cast<HashTable*>(obj);
1637}
1638
1639
1640INT_ACCESSORS(Array, length, kLengthOffset)
1641
1642
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001643INT_ACCESSORS(String, length, kLengthOffset)
1644
1645
1646uint32_t String::hash_field() {
1647 return READ_UINT32_FIELD(this, kHashFieldOffset);
1648}
1649
1650
1651void String::set_hash_field(uint32_t value) {
1652 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1653}
1654
1655
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656bool String::Equals(String* other) {
1657 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001658 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1659 return false;
1660 }
1661 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001662}
1663
1664
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001665Object* String::TryFlatten(PretenureFlag pretenure) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001666 // We don't need to flatten strings that are already flat. Since this code
1667 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001668 if (IsFlat()) return this;
1669 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670}
1671
1672
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001673uint16_t String::Get(int index) {
1674 ASSERT(index >= 0 && index < length());
1675 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001676 case kSeqStringTag | kAsciiStringTag:
1677 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1678 case kSeqStringTag | kTwoByteStringTag:
1679 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1680 case kConsStringTag | kAsciiStringTag:
1681 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001682 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001683 case kExternalStringTag | kAsciiStringTag:
1684 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1685 case kExternalStringTag | kTwoByteStringTag:
1686 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001687 default:
1688 break;
1689 }
1690
1691 UNREACHABLE();
1692 return 0;
1693}
1694
1695
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001696void String::Set(int index, uint16_t value) {
1697 ASSERT(index >= 0 && index < length());
1698 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699
ager@chromium.org5ec48922009-05-05 07:25:34 +00001700 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001701 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1702 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703}
1704
1705
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001706bool String::IsFlat() {
1707 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001708 case kConsStringTag: {
1709 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001710 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001711 return second->length() == 0;
1712 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001713 default:
1714 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 }
1716}
1717
1718
ager@chromium.org7c537e22008-10-16 08:43:32 +00001719uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720 ASSERT(index >= 0 && index < length());
1721 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1722}
1723
1724
ager@chromium.org7c537e22008-10-16 08:43:32 +00001725void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1727 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1728 static_cast<byte>(value));
1729}
1730
1731
ager@chromium.org7c537e22008-10-16 08:43:32 +00001732Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733 return FIELD_ADDR(this, kHeaderSize);
1734}
1735
1736
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001737char* SeqAsciiString::GetChars() {
1738 return reinterpret_cast<char*>(GetCharsAddress());
1739}
1740
1741
ager@chromium.org7c537e22008-10-16 08:43:32 +00001742Address SeqTwoByteString::GetCharsAddress() {
1743 return FIELD_ADDR(this, kHeaderSize);
1744}
1745
1746
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001747uc16* SeqTwoByteString::GetChars() {
1748 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1749}
1750
1751
ager@chromium.org7c537e22008-10-16 08:43:32 +00001752uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753 ASSERT(index >= 0 && index < length());
1754 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1755}
1756
1757
ager@chromium.org7c537e22008-10-16 08:43:32 +00001758void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001759 ASSERT(index >= 0 && index < length());
1760 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1761}
1762
1763
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001764int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001765 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766 return SizeFor(length);
1767}
1768
1769
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001770int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772 return SizeFor(length);
1773}
1774
1775
ager@chromium.org870a0b62008-11-04 11:43:05 +00001776String* ConsString::first() {
1777 return String::cast(READ_FIELD(this, kFirstOffset));
1778}
1779
1780
1781Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 return READ_FIELD(this, kFirstOffset);
1783}
1784
1785
ager@chromium.org870a0b62008-11-04 11:43:05 +00001786void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001788 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001789}
1790
1791
ager@chromium.org870a0b62008-11-04 11:43:05 +00001792String* ConsString::second() {
1793 return String::cast(READ_FIELD(this, kSecondOffset));
1794}
1795
1796
1797Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 return READ_FIELD(this, kSecondOffset);
1799}
1800
1801
ager@chromium.org870a0b62008-11-04 11:43:05 +00001802void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001804 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805}
1806
1807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1809 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1810}
1811
1812
1813void ExternalAsciiString::set_resource(
1814 ExternalAsciiString::Resource* resource) {
1815 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1816}
1817
1818
1819ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1820 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1821}
1822
1823
1824void ExternalTwoByteString::set_resource(
1825 ExternalTwoByteString::Resource* resource) {
1826 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1827}
1828
1829
1830byte ByteArray::get(int index) {
1831 ASSERT(index >= 0 && index < this->length());
1832 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1833}
1834
1835
1836void ByteArray::set(int index, byte value) {
1837 ASSERT(index >= 0 && index < this->length());
1838 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1839}
1840
1841
1842int ByteArray::get_int(int index) {
1843 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1844 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1845}
1846
1847
1848ByteArray* ByteArray::FromDataStartAddress(Address address) {
1849 ASSERT_TAG_ALIGNED(address);
1850 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1851}
1852
1853
1854Address ByteArray::GetDataStartAddress() {
1855 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1856}
1857
1858
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001859uint8_t* PixelArray::external_pointer() {
1860 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1861 return reinterpret_cast<uint8_t*>(ptr);
1862}
1863
1864
1865void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1866 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1867 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1868}
1869
1870
1871uint8_t PixelArray::get(int index) {
1872 ASSERT((index >= 0) && (index < this->length()));
1873 uint8_t* ptr = external_pointer();
1874 return ptr[index];
1875}
1876
1877
1878void PixelArray::set(int index, uint8_t value) {
1879 ASSERT((index >= 0) && (index < this->length()));
1880 uint8_t* ptr = external_pointer();
1881 ptr[index] = value;
1882}
1883
1884
ager@chromium.org3811b432009-10-28 14:53:37 +00001885void* ExternalArray::external_pointer() {
1886 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1887 return reinterpret_cast<void*>(ptr);
1888}
1889
1890
1891void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1892 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1893 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1894}
1895
1896
1897int8_t ExternalByteArray::get(int index) {
1898 ASSERT((index >= 0) && (index < this->length()));
1899 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1900 return ptr[index];
1901}
1902
1903
1904void ExternalByteArray::set(int index, int8_t value) {
1905 ASSERT((index >= 0) && (index < this->length()));
1906 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1907 ptr[index] = value;
1908}
1909
1910
1911uint8_t ExternalUnsignedByteArray::get(int index) {
1912 ASSERT((index >= 0) && (index < this->length()));
1913 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1914 return ptr[index];
1915}
1916
1917
1918void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1919 ASSERT((index >= 0) && (index < this->length()));
1920 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1921 ptr[index] = value;
1922}
1923
1924
1925int16_t ExternalShortArray::get(int index) {
1926 ASSERT((index >= 0) && (index < this->length()));
1927 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1928 return ptr[index];
1929}
1930
1931
1932void ExternalShortArray::set(int index, int16_t value) {
1933 ASSERT((index >= 0) && (index < this->length()));
1934 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1935 ptr[index] = value;
1936}
1937
1938
1939uint16_t ExternalUnsignedShortArray::get(int index) {
1940 ASSERT((index >= 0) && (index < this->length()));
1941 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1942 return ptr[index];
1943}
1944
1945
1946void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1947 ASSERT((index >= 0) && (index < this->length()));
1948 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1949 ptr[index] = value;
1950}
1951
1952
1953int32_t ExternalIntArray::get(int index) {
1954 ASSERT((index >= 0) && (index < this->length()));
1955 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1956 return ptr[index];
1957}
1958
1959
1960void ExternalIntArray::set(int index, int32_t value) {
1961 ASSERT((index >= 0) && (index < this->length()));
1962 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1963 ptr[index] = value;
1964}
1965
1966
1967uint32_t ExternalUnsignedIntArray::get(int index) {
1968 ASSERT((index >= 0) && (index < this->length()));
1969 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1970 return ptr[index];
1971}
1972
1973
1974void ExternalUnsignedIntArray::set(int index, uint32_t value) {
1975 ASSERT((index >= 0) && (index < this->length()));
1976 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1977 ptr[index] = value;
1978}
1979
1980
1981float ExternalFloatArray::get(int index) {
1982 ASSERT((index >= 0) && (index < this->length()));
1983 float* ptr = static_cast<float*>(external_pointer());
1984 return ptr[index];
1985}
1986
1987
1988void ExternalFloatArray::set(int index, float value) {
1989 ASSERT((index >= 0) && (index < this->length()));
1990 float* ptr = static_cast<float*>(external_pointer());
1991 ptr[index] = value;
1992}
1993
1994
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001996 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
1997}
1998
1999
2000int Map::inobject_properties() {
2001 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002002}
2003
2004
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002005int Map::pre_allocated_property_fields() {
2006 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2007}
2008
2009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002010int HeapObject::SizeFromMap(Map* map) {
2011 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002012 // Only inline the most frequent cases.
2013 if (instance_type == JS_OBJECT_TYPE ||
2014 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2015 (kStringTag | kConsStringTag) ||
2016 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017 if (instance_type == FIXED_ARRAY_TYPE) {
2018 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2019 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002020 if (instance_type == BYTE_ARRAY_TYPE) {
2021 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2022 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023 // Otherwise do the general size computation.
2024 return SlowSizeFromMap(map);
2025}
2026
2027
2028void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002029 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002030 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031 ASSERT(0 <= value && value < 256);
2032 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2033}
2034
2035
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036void Map::set_inobject_properties(int value) {
2037 ASSERT(0 <= value && value < 256);
2038 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2039}
2040
2041
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002042void Map::set_pre_allocated_property_fields(int value) {
2043 ASSERT(0 <= value && value < 256);
2044 WRITE_BYTE_FIELD(this,
2045 kPreAllocatedPropertyFieldsOffset,
2046 static_cast<byte>(value));
2047}
2048
2049
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002050InstanceType Map::instance_type() {
2051 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2052}
2053
2054
2055void Map::set_instance_type(InstanceType value) {
2056 ASSERT(0 <= value && value < 256);
2057 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2058}
2059
2060
2061int Map::unused_property_fields() {
2062 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2063}
2064
2065
2066void Map::set_unused_property_fields(int value) {
2067 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2068}
2069
2070
2071byte Map::bit_field() {
2072 return READ_BYTE_FIELD(this, kBitFieldOffset);
2073}
2074
2075
2076void Map::set_bit_field(byte value) {
2077 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2078}
2079
2080
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002081byte Map::bit_field2() {
2082 return READ_BYTE_FIELD(this, kBitField2Offset);
2083}
2084
2085
2086void Map::set_bit_field2(byte value) {
2087 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2088}
2089
2090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091void Map::set_non_instance_prototype(bool value) {
2092 if (value) {
2093 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2094 } else {
2095 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2096 }
2097}
2098
2099
2100bool Map::has_non_instance_prototype() {
2101 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2102}
2103
2104
ager@chromium.org870a0b62008-11-04 11:43:05 +00002105void Map::set_is_access_check_needed(bool access_check_needed) {
2106 if (access_check_needed) {
2107 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2108 } else {
2109 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2110 }
2111}
2112
2113
2114bool Map::is_access_check_needed() {
2115 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2116}
2117
2118
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119Code::Flags Code::flags() {
2120 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2121}
2122
2123
2124void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002125 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126 // Make sure that all call stubs have an arguments count.
2127 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2128 ExtractArgumentsCountFromFlags(flags) >= 0);
2129 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2130}
2131
2132
2133Code::Kind Code::kind() {
2134 return ExtractKindFromFlags(flags());
2135}
2136
2137
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002138InLoopFlag Code::ic_in_loop() {
2139 return ExtractICInLoopFromFlags(flags());
2140}
2141
2142
kasper.lund7276f142008-07-30 08:49:36 +00002143InlineCacheState Code::ic_state() {
2144 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145 // Only allow uninitialized or debugger states for non-IC code
2146 // objects. This is used in the debugger to determine whether or not
2147 // a call to code object has been replaced with a debug break call.
2148 ASSERT(is_inline_cache_stub() ||
2149 result == UNINITIALIZED ||
2150 result == DEBUG_BREAK ||
2151 result == DEBUG_PREPARE_STEP_IN);
2152 return result;
2153}
2154
2155
2156PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002157 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158 return ExtractTypeFromFlags(flags());
2159}
2160
2161
2162int Code::arguments_count() {
2163 ASSERT(is_call_stub() || kind() == STUB);
2164 return ExtractArgumentsCountFromFlags(flags());
2165}
2166
2167
2168CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002169 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002170 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2171 kStubMajorKeyOffset));
2172}
2173
2174
2175void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002176 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002177 ASSERT(0 <= major && major < 256);
2178 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179}
2180
2181
2182bool Code::is_inline_cache_stub() {
2183 Kind kind = this->kind();
2184 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2185}
2186
2187
2188Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002189 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002190 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191 PropertyType type,
2192 int argc) {
2193 // Compute the bit mask.
2194 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002195 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002196 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002197 bits |= type << kFlagsTypeShift;
2198 bits |= argc << kFlagsArgumentsCountShift;
2199 // Cast to flags and validate result before returning it.
2200 Flags result = static_cast<Flags>(bits);
2201 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002202 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002203 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204 ASSERT(ExtractTypeFromFlags(result) == type);
2205 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2206 return result;
2207}
2208
2209
2210Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2211 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002212 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002214 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215}
2216
2217
2218Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2219 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2220 return static_cast<Kind>(bits);
2221}
2222
2223
kasper.lund7276f142008-07-30 08:49:36 +00002224InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2225 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226 return static_cast<InlineCacheState>(bits);
2227}
2228
2229
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002230InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2231 int bits = (flags & kFlagsICInLoopMask);
2232 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2233}
2234
2235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2237 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2238 return static_cast<PropertyType>(bits);
2239}
2240
2241
2242int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2243 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2244}
2245
2246
2247Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2248 int bits = flags & ~kFlagsTypeMask;
2249 return static_cast<Flags>(bits);
2250}
2251
2252
ager@chromium.org8bb60582008-12-11 12:02:20 +00002253Code* Code::GetCodeFromTargetAddress(Address address) {
2254 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2255 // GetCodeFromTargetAddress might be called when marking objects during mark
2256 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2257 // Code::cast. Code::cast does not work when the object's map is
2258 // marked.
2259 Code* result = reinterpret_cast<Code*>(code);
2260 return result;
2261}
2262
2263
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264Object* Map::prototype() {
2265 return READ_FIELD(this, kPrototypeOffset);
2266}
2267
2268
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002269void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002270 ASSERT(value->IsNull() || value->IsJSObject());
2271 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002272 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273}
2274
2275
2276ACCESSORS(Map, instance_descriptors, DescriptorArray,
2277 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002278ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279ACCESSORS(Map, constructor, Object, kConstructorOffset)
2280
2281ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2282ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2283
2284ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2285ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002286ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002288ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289
2290ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2291ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2292ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2293ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2294ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002295ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002296
2297ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2298ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2299ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2300
2301ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2302ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2303ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2304ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2305ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2306ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2307
2308ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2309ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2310
2311ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2312ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2313
2314ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2315ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002316ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2317 kPropertyAccessorsOffset)
2318ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2319 kPrototypeTemplateOffset)
2320ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2321ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2322 kNamedPropertyHandlerOffset)
2323ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2324 kIndexedPropertyHandlerOffset)
2325ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2326 kInstanceTemplateOffset)
2327ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2328ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2330 kInstanceCallHandlerOffset)
2331ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2332 kAccessCheckInfoOffset)
2333ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2334
2335ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002336ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2337 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338
2339ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2340ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2341
2342ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2343
2344ACCESSORS(Script, source, Object, kSourceOffset)
2345ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002346ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2348ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002349ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002350ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2352ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002353ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002354ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002355ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002356ACCESSORS(Script, eval_from_instructions_offset, Smi,
2357 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002359#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2361ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2362ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2363ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2364
2365ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2366ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2367ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2368ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002369#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002371ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2373ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2374 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002375ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2377ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002378ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002379ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2380 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381
2382BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2383 kHiddenPrototypeBit)
2384BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2385BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2386 kNeedsAccessCheckBit)
2387BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2388 kIsExpressionBit)
2389BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2390 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002391BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002392 has_only_simple_this_property_assignments,
2393 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002394BOOL_ACCESSORS(SharedFunctionInfo,
2395 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002396 try_full_codegen,
2397 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398
2399INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2400INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2401 kFormalParameterCountOffset)
2402INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2403 kExpectedNofPropertiesOffset)
2404INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2405 kStartPositionAndTypeOffset)
2406INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2407INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2408 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002409INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2410 kCompilerHintsOffset)
2411INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2412 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002413
2414
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002415ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2416ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2417
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002418bool Script::HasValidSource() {
2419 Object* src = this->source();
2420 if (!src->IsString()) return true;
2421 String* src_str = String::cast(src);
2422 if (!StringShape(src_str).IsExternal()) return true;
2423 if (src_str->IsAsciiRepresentation()) {
2424 return ExternalAsciiString::cast(src)->resource() != NULL;
2425 } else if (src_str->IsTwoByteRepresentation()) {
2426 return ExternalTwoByteString::cast(src)->resource() != NULL;
2427 }
2428 return true;
2429}
2430
2431
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002432void SharedFunctionInfo::DontAdaptArguments() {
2433 ASSERT(code()->kind() == Code::BUILTIN);
2434 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2435}
2436
2437
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002438int SharedFunctionInfo::start_position() {
2439 return start_position_and_type() >> kStartPositionShift;
2440}
2441
2442
2443void SharedFunctionInfo::set_start_position(int start_position) {
2444 set_start_position_and_type((start_position << kStartPositionShift)
2445 | (start_position_and_type() & ~kStartPositionMask));
2446}
2447
2448
2449Code* SharedFunctionInfo::code() {
2450 return Code::cast(READ_FIELD(this, kCodeOffset));
2451}
2452
2453
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002454void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002455 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002456 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002457}
2458
2459
2460bool SharedFunctionInfo::is_compiled() {
2461 // TODO(1242782): Create a code kind for uncompiled code.
2462 return code()->kind() != Code::STUB;
2463}
2464
2465
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002466bool SharedFunctionInfo::IsApiFunction() {
2467 return function_data()->IsFunctionTemplateInfo();
2468}
2469
2470
2471FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2472 ASSERT(IsApiFunction());
2473 return FunctionTemplateInfo::cast(function_data());
2474}
2475
2476
2477bool SharedFunctionInfo::HasCustomCallGenerator() {
2478 return function_data()->IsProxy();
2479}
2480
2481
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482bool JSFunction::IsBoilerplate() {
2483 return map() == Heap::boilerplate_function_map();
2484}
2485
2486
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002487bool JSFunction::IsBuiltin() {
2488 return context()->global()->IsJSBuiltinsObject();
2489}
2490
2491
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002492bool JSObject::IsLoaded() {
2493 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002494}
2495
2496
2497Code* JSFunction::code() {
2498 return shared()->code();
2499}
2500
2501
2502void JSFunction::set_code(Code* value) {
2503 shared()->set_code(value);
2504}
2505
2506
2507Context* JSFunction::context() {
2508 return Context::cast(READ_FIELD(this, kContextOffset));
2509}
2510
2511
2512Object* JSFunction::unchecked_context() {
2513 return READ_FIELD(this, kContextOffset);
2514}
2515
2516
2517void JSFunction::set_context(Object* value) {
2518 ASSERT(value == Heap::undefined_value() || value->IsContext());
2519 WRITE_FIELD(this, kContextOffset, value);
2520 WRITE_BARRIER(this, kContextOffset);
2521}
2522
2523ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2524 kPrototypeOrInitialMapOffset)
2525
2526
2527Map* JSFunction::initial_map() {
2528 return Map::cast(prototype_or_initial_map());
2529}
2530
2531
2532void JSFunction::set_initial_map(Map* value) {
2533 set_prototype_or_initial_map(value);
2534}
2535
2536
2537bool JSFunction::has_initial_map() {
2538 return prototype_or_initial_map()->IsMap();
2539}
2540
2541
2542bool JSFunction::has_instance_prototype() {
2543 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2544}
2545
2546
2547bool JSFunction::has_prototype() {
2548 return map()->has_non_instance_prototype() || has_instance_prototype();
2549}
2550
2551
2552Object* JSFunction::instance_prototype() {
2553 ASSERT(has_instance_prototype());
2554 if (has_initial_map()) return initial_map()->prototype();
2555 // When there is no initial map and the prototype is a JSObject, the
2556 // initial map field is used for the prototype field.
2557 return prototype_or_initial_map();
2558}
2559
2560
2561Object* JSFunction::prototype() {
2562 ASSERT(has_prototype());
2563 // If the function's prototype property has been set to a non-JSObject
2564 // value, that value is stored in the constructor field of the map.
2565 if (map()->has_non_instance_prototype()) return map()->constructor();
2566 return instance_prototype();
2567}
2568
2569
2570bool JSFunction::is_compiled() {
2571 return shared()->is_compiled();
2572}
2573
2574
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002575int JSFunction::NumberOfLiterals() {
2576 return literals()->length();
2577}
2578
2579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2581 ASSERT(0 <= id && id < kJSBuiltinsCount);
2582 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2583}
2584
2585
2586void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2587 Object* value) {
2588 ASSERT(0 <= id && id < kJSBuiltinsCount);
2589 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2590 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2591}
2592
2593
2594Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002595 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002596}
2597
2598
2599void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002600 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002601}
2602
2603
2604void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2605 visitor->VisitExternalReference(
2606 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2607}
2608
2609
2610ACCESSORS(JSValue, value, Object, kValueOffset)
2611
2612
2613JSValue* JSValue::cast(Object* obj) {
2614 ASSERT(obj->IsJSValue());
2615 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2616 return reinterpret_cast<JSValue*>(obj);
2617}
2618
2619
2620INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2621INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2622INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2623
2624
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002625byte* Code::instruction_start() {
2626 return FIELD_ADDR(this, kHeaderSize);
2627}
2628
2629
2630int Code::body_size() {
2631 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2632}
2633
2634
2635byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002636 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637}
2638
2639
2640byte* Code::entry() {
2641 return instruction_start();
2642}
2643
2644
2645bool Code::contains(byte* pc) {
2646 return (instruction_start() <= pc) &&
2647 (pc < instruction_start() + instruction_size());
2648}
2649
2650
2651byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002652 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653}
2654
2655
2656ACCESSORS(JSArray, length, Object, kLengthOffset)
2657
2658
ager@chromium.org236ad962008-09-25 09:45:57 +00002659ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002660
2661
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002662JSRegExp::Type JSRegExp::TypeTag() {
2663 Object* data = this->data();
2664 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2665 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2666 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002667}
2668
2669
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002670int JSRegExp::CaptureCount() {
2671 switch (TypeTag()) {
2672 case ATOM:
2673 return 0;
2674 case IRREGEXP:
2675 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2676 default:
2677 UNREACHABLE();
2678 return -1;
2679 }
2680}
2681
2682
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002683JSRegExp::Flags JSRegExp::GetFlags() {
2684 ASSERT(this->data()->IsFixedArray());
2685 Object* data = this->data();
2686 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2687 return Flags(smi->value());
2688}
2689
2690
2691String* JSRegExp::Pattern() {
2692 ASSERT(this->data()->IsFixedArray());
2693 Object* data = this->data();
2694 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2695 return pattern;
2696}
2697
2698
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002699Object* JSRegExp::DataAt(int index) {
2700 ASSERT(TypeTag() != NOT_COMPILED);
2701 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002702}
2703
2704
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002705void JSRegExp::SetDataAt(int index, Object* value) {
2706 ASSERT(TypeTag() != NOT_COMPILED);
2707 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2708 FixedArray::cast(data())->set(index, value);
2709}
2710
2711
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002712JSObject::ElementsKind JSObject::GetElementsKind() {
2713 Array* array = elements();
2714 if (array->IsFixedArray()) {
2715 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2716 if (array->map() == Heap::fixed_array_map()) {
2717 return FAST_ELEMENTS;
2718 }
2719 ASSERT(array->IsDictionary());
2720 return DICTIONARY_ELEMENTS;
2721 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002722 if (array->IsExternalArray()) {
2723 switch (array->map()->instance_type()) {
2724 case EXTERNAL_BYTE_ARRAY_TYPE:
2725 return EXTERNAL_BYTE_ELEMENTS;
2726 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2727 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2728 case EXTERNAL_SHORT_ARRAY_TYPE:
2729 return EXTERNAL_SHORT_ELEMENTS;
2730 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2731 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2732 case EXTERNAL_INT_ARRAY_TYPE:
2733 return EXTERNAL_INT_ELEMENTS;
2734 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2735 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2736 default:
2737 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2738 return EXTERNAL_FLOAT_ELEMENTS;
2739 }
2740 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002741 ASSERT(array->IsPixelArray());
2742 return PIXEL_ELEMENTS;
2743}
2744
2745
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002746bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002747 return GetElementsKind() == FAST_ELEMENTS;
2748}
2749
2750
2751bool JSObject::HasDictionaryElements() {
2752 return GetElementsKind() == DICTIONARY_ELEMENTS;
2753}
2754
2755
2756bool JSObject::HasPixelElements() {
2757 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758}
2759
2760
ager@chromium.org3811b432009-10-28 14:53:37 +00002761bool JSObject::HasExternalArrayElements() {
2762 return (HasExternalByteElements() ||
2763 HasExternalUnsignedByteElements() ||
2764 HasExternalShortElements() ||
2765 HasExternalUnsignedShortElements() ||
2766 HasExternalIntElements() ||
2767 HasExternalUnsignedIntElements() ||
2768 HasExternalFloatElements());
2769}
2770
2771
2772bool JSObject::HasExternalByteElements() {
2773 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2774}
2775
2776
2777bool JSObject::HasExternalUnsignedByteElements() {
2778 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2779}
2780
2781
2782bool JSObject::HasExternalShortElements() {
2783 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2784}
2785
2786
2787bool JSObject::HasExternalUnsignedShortElements() {
2788 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2789}
2790
2791
2792bool JSObject::HasExternalIntElements() {
2793 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2794}
2795
2796
2797bool JSObject::HasExternalUnsignedIntElements() {
2798 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2799}
2800
2801
2802bool JSObject::HasExternalFloatElements() {
2803 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2804}
2805
2806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807bool JSObject::HasNamedInterceptor() {
2808 return map()->has_named_interceptor();
2809}
2810
2811
2812bool JSObject::HasIndexedInterceptor() {
2813 return map()->has_indexed_interceptor();
2814}
2815
2816
ager@chromium.org5c838252010-02-19 08:53:10 +00002817bool JSObject::AllowsSetElementsLength() {
2818 bool result = elements()->IsFixedArray();
2819 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2820 return result;
2821}
2822
2823
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002824StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002826 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827}
2828
2829
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002830NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002831 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002832 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833}
2834
2835
2836bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002837 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002838}
2839
2840
2841uint32_t String::Hash() {
2842 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002843 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002844 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002845 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846 return ComputeAndSetHash();
2847}
2848
2849
ager@chromium.org7c537e22008-10-16 08:43:32 +00002850StringHasher::StringHasher(int length)
2851 : length_(length),
2852 raw_running_hash_(0),
2853 array_index_(0),
2854 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2855 is_first_char_(true),
2856 is_valid_(true) { }
2857
2858
2859bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002860 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002861}
2862
2863
2864void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002865 // Use the Jenkins one-at-a-time hash function to update the hash
2866 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002867 raw_running_hash_ += c;
2868 raw_running_hash_ += (raw_running_hash_ << 10);
2869 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002870 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002871 if (is_array_index_) {
2872 if (c < '0' || c > '9') {
2873 is_array_index_ = false;
2874 } else {
2875 int d = c - '0';
2876 if (is_first_char_) {
2877 is_first_char_ = false;
2878 if (c == '0' && length_ > 1) {
2879 is_array_index_ = false;
2880 return;
2881 }
2882 }
2883 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2884 is_array_index_ = false;
2885 } else {
2886 array_index_ = array_index_ * 10 + d;
2887 }
2888 }
2889 }
2890}
2891
2892
2893void StringHasher::AddCharacterNoIndex(uc32 c) {
2894 ASSERT(!is_array_index());
2895 raw_running_hash_ += c;
2896 raw_running_hash_ += (raw_running_hash_ << 10);
2897 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2898}
2899
2900
2901uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002902 // Get the calculated raw hash value and do some more bit ops to distribute
2903 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002904 uint32_t result = raw_running_hash_;
2905 result += (result << 3);
2906 result ^= (result >> 11);
2907 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002908 if (result == 0) {
2909 result = 27;
2910 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002911 return result;
2912}
2913
2914
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002916 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002917 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002918 return SlowAsArrayIndex(index);
2919}
2920
2921
2922Object* JSObject::GetPrototype() {
2923 return JSObject::cast(this)->map()->prototype();
2924}
2925
2926
2927PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2928 return GetPropertyAttributeWithReceiver(this, key);
2929}
2930
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002931// TODO(504): this may be useful in other places too where JSGlobalProxy
2932// is used.
2933Object* JSObject::BypassGlobalProxy() {
2934 if (IsJSGlobalProxy()) {
2935 Object* proto = GetPrototype();
2936 if (proto->IsNull()) return Heap::undefined_value();
2937 ASSERT(proto->IsJSGlobalObject());
2938 return proto;
2939 }
2940 return this;
2941}
2942
2943
2944bool JSObject::HasHiddenPropertiesObject() {
2945 ASSERT(!IsJSGlobalProxy());
2946 return GetPropertyAttributePostInterceptor(this,
2947 Heap::hidden_symbol(),
2948 false) != ABSENT;
2949}
2950
2951
2952Object* JSObject::GetHiddenPropertiesObject() {
2953 ASSERT(!IsJSGlobalProxy());
2954 PropertyAttributes attributes;
2955 return GetLocalPropertyPostInterceptor(this,
2956 Heap::hidden_symbol(),
2957 &attributes);
2958}
2959
2960
2961Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2962 ASSERT(!IsJSGlobalProxy());
2963 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2964 hidden_obj,
2965 DONT_ENUM);
2966}
2967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968
2969bool JSObject::HasElement(uint32_t index) {
2970 return HasElementWithReceiver(this, index);
2971}
2972
2973
2974bool AccessorInfo::all_can_read() {
2975 return BooleanBit::get(flag(), kAllCanReadBit);
2976}
2977
2978
2979void AccessorInfo::set_all_can_read(bool value) {
2980 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2981}
2982
2983
2984bool AccessorInfo::all_can_write() {
2985 return BooleanBit::get(flag(), kAllCanWriteBit);
2986}
2987
2988
2989void AccessorInfo::set_all_can_write(bool value) {
2990 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2991}
2992
2993
ager@chromium.org870a0b62008-11-04 11:43:05 +00002994bool AccessorInfo::prohibits_overwriting() {
2995 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2996}
2997
2998
2999void AccessorInfo::set_prohibits_overwriting(bool value) {
3000 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3001}
3002
3003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004PropertyAttributes AccessorInfo::property_attributes() {
3005 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3006}
3007
3008
3009void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3010 ASSERT(AttributesField::is_valid(attributes));
3011 int rest_value = flag()->value() & ~AttributesField::mask();
3012 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3013}
3014
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003015template<typename Shape, typename Key>
3016void Dictionary<Shape, Key>::SetEntry(int entry,
3017 Object* key,
3018 Object* value,
3019 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003020 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003021 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003022 AssertNoAllocation no_gc;
3023 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003024 FixedArray::set(index, key, mode);
3025 FixedArray::set(index+1, value, mode);
3026 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003027}
3028
3029
3030void Map::ClearCodeCache() {
3031 // No write barrier is needed since empty_fixed_array is not in new space.
3032 // Please note this function is used during marking:
3033 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003034 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3035 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003036}
3037
3038
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003039void JSArray::EnsureSize(int required_size) {
3040 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003041 Array* elts = elements();
3042 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3043 if (elts->length() < required_size) {
3044 // Doubling in size would be overkill, but leave some slack to avoid
3045 // constantly growing.
3046 Expand(required_size + (required_size >> 3));
3047 // It's a performance benefit to keep a frequently used array in new-space.
3048 } else if (!Heap::new_space()->Contains(elts) &&
3049 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3050 // Expand will allocate a new backing store in new space even if the size
3051 // we asked for isn't larger than what we had before.
3052 Expand(required_size);
3053 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003054}
3055
3056
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003057void JSArray::set_length(Smi* length) {
3058 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3059}
3060
3061
ager@chromium.org7c537e22008-10-16 08:43:32 +00003062void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003063 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003064 set_elements(storage);
3065}
3066
3067
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003068Object* FixedArray::Copy() {
3069 if (length() == 0) return this;
3070 return Heap::CopyFixedArray(this);
3071}
3072
3073
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003074#undef CAST_ACCESSOR
3075#undef INT_ACCESSORS
3076#undef SMI_ACCESSORS
3077#undef ACCESSORS
3078#undef FIELD_ADDR
3079#undef READ_FIELD
3080#undef WRITE_FIELD
3081#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003082#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003083#undef READ_MEMADDR_FIELD
3084#undef WRITE_MEMADDR_FIELD
3085#undef READ_DOUBLE_FIELD
3086#undef WRITE_DOUBLE_FIELD
3087#undef READ_INT_FIELD
3088#undef WRITE_INT_FIELD
3089#undef READ_SHORT_FIELD
3090#undef WRITE_SHORT_FIELD
3091#undef READ_BYTE_FIELD
3092#undef WRITE_BYTE_FIELD
3093
3094
3095} } // namespace v8::internal
3096
3097#endif // V8_OBJECTS_INL_H_