blob: ad151041528b3a7e4b75146eda063f7f68e09549 [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
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000258bool String::IsExternalTwoByteStringWithAsciiChars() {
259 if (!IsExternalTwoByteString()) return false;
260 const uc16* data = ExternalTwoByteString::cast(this)->resource()->data();
261 for (int i = 0, len = length(); i < len; i++) {
262 if (data[i] > kMaxAsciiCharCode) return false;
263 }
264 return true;
265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268bool StringShape::IsCons() {
269 return (type_ & kStringRepresentationMask) == kConsStringTag;
270}
271
272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273bool StringShape::IsExternal() {
274 return (type_ & kStringRepresentationMask) == kExternalStringTag;
275}
276
277
278bool StringShape::IsSequential() {
279 return (type_ & kStringRepresentationMask) == kSeqStringTag;
280}
281
282
283StringRepresentationTag StringShape::representation_tag() {
284 uint32_t tag = (type_ & kStringRepresentationMask);
285 return static_cast<StringRepresentationTag>(tag);
286}
287
288
289uint32_t StringShape::full_representation_tag() {
290 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
291}
292
293
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000294STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
295 Internals::kFullStringRepresentationMask);
296
297
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298bool StringShape::IsSequentialAscii() {
299 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305}
306
307
308bool StringShape::IsExternalAscii() {
309 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315}
316
317
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000318STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
319 Internals::kExternalTwoByteRepresentationTag);
320
321
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000322uc32 FlatStringReader::Get(int index) {
323 ASSERT(0 <= index && index <= length_);
324 if (is_ascii_) {
325 return static_cast<const byte*>(start_)[index];
326 } else {
327 return static_cast<const uc16*>(start_)[index];
328 }
329}
330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332bool Object::IsNumber() {
333 return IsSmi() || IsHeapNumber();
334}
335
336
337bool Object::IsByteArray() {
338 return Object::IsHeapObject()
339 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
340}
341
342
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000343bool Object::IsPixelArray() {
344 return Object::IsHeapObject() &&
345 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
346}
347
348
ager@chromium.org3811b432009-10-28 14:53:37 +0000349bool Object::IsExternalArray() {
350 if (!Object::IsHeapObject())
351 return false;
352 InstanceType instance_type =
353 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000354 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
355 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000356}
357
358
359bool Object::IsExternalByteArray() {
360 return Object::IsHeapObject() &&
361 HeapObject::cast(this)->map()->instance_type() ==
362 EXTERNAL_BYTE_ARRAY_TYPE;
363}
364
365
366bool Object::IsExternalUnsignedByteArray() {
367 return Object::IsHeapObject() &&
368 HeapObject::cast(this)->map()->instance_type() ==
369 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
370}
371
372
373bool Object::IsExternalShortArray() {
374 return Object::IsHeapObject() &&
375 HeapObject::cast(this)->map()->instance_type() ==
376 EXTERNAL_SHORT_ARRAY_TYPE;
377}
378
379
380bool Object::IsExternalUnsignedShortArray() {
381 return Object::IsHeapObject() &&
382 HeapObject::cast(this)->map()->instance_type() ==
383 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
384}
385
386
387bool Object::IsExternalIntArray() {
388 return Object::IsHeapObject() &&
389 HeapObject::cast(this)->map()->instance_type() ==
390 EXTERNAL_INT_ARRAY_TYPE;
391}
392
393
394bool Object::IsExternalUnsignedIntArray() {
395 return Object::IsHeapObject() &&
396 HeapObject::cast(this)->map()->instance_type() ==
397 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
398}
399
400
401bool Object::IsExternalFloatArray() {
402 return Object::IsHeapObject() &&
403 HeapObject::cast(this)->map()->instance_type() ==
404 EXTERNAL_FLOAT_ARRAY_TYPE;
405}
406
407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000408bool Object::IsFailure() {
409 return HAS_FAILURE_TAG(this);
410}
411
412
413bool Object::IsRetryAfterGC() {
414 return HAS_FAILURE_TAG(this)
415 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
416}
417
418
ager@chromium.org7c537e22008-10-16 08:43:32 +0000419bool Object::IsOutOfMemoryFailure() {
420 return HAS_FAILURE_TAG(this)
421 && Failure::cast(this)->IsOutOfMemoryException();
422}
423
424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425bool Object::IsException() {
426 return this == Failure::Exception();
427}
428
429
430bool Object::IsJSObject() {
431 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000432 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433}
434
435
ager@chromium.org32912102009-01-16 10:38:43 +0000436bool Object::IsJSContextExtensionObject() {
437 return IsHeapObject()
438 && (HeapObject::cast(this)->map()->instance_type() ==
439 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
440}
441
442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000443bool Object::IsMap() {
444 return Object::IsHeapObject()
445 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
446}
447
448
449bool Object::IsFixedArray() {
450 return Object::IsHeapObject()
451 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
452}
453
454
455bool Object::IsDescriptorArray() {
456 return IsFixedArray();
457}
458
459
460bool Object::IsContext() {
461 return Object::IsHeapObject()
462 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000463 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464 HeapObject::cast(this)->map() == Heap::global_context_map());
465}
466
467
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000468bool Object::IsCatchContext() {
469 return Object::IsHeapObject()
470 && HeapObject::cast(this)->map() == Heap::catch_context_map();
471}
472
473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474bool Object::IsGlobalContext() {
475 return Object::IsHeapObject()
476 && HeapObject::cast(this)->map() == Heap::global_context_map();
477}
478
479
480bool Object::IsJSFunction() {
481 return Object::IsHeapObject()
482 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
483}
484
485
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000486template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487 return obj->IsJSFunction();
488}
489
490
491bool Object::IsCode() {
492 return Object::IsHeapObject()
493 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
494}
495
496
497bool Object::IsOddball() {
498 return Object::IsHeapObject()
499 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
500}
501
502
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000503bool Object::IsJSGlobalPropertyCell() {
504 return Object::IsHeapObject()
505 && HeapObject::cast(this)->map()->instance_type()
506 == JS_GLOBAL_PROPERTY_CELL_TYPE;
507}
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510bool Object::IsSharedFunctionInfo() {
511 return Object::IsHeapObject() &&
512 (HeapObject::cast(this)->map()->instance_type() ==
513 SHARED_FUNCTION_INFO_TYPE);
514}
515
516
517bool Object::IsJSValue() {
518 return Object::IsHeapObject()
519 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
520}
521
522
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000523bool Object::IsStringWrapper() {
524 return IsJSValue() && JSValue::cast(this)->value()->IsString();
525}
526
527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528bool Object::IsProxy() {
529 return Object::IsHeapObject()
530 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
531}
532
533
534bool Object::IsBoolean() {
535 return IsTrue() || IsFalse();
536}
537
538
539bool Object::IsJSArray() {
540 return Object::IsHeapObject()
541 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
542}
543
544
ager@chromium.org236ad962008-09-25 09:45:57 +0000545bool Object::IsJSRegExp() {
546 return Object::IsHeapObject()
547 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
548}
549
550
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000551template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552 return obj->IsJSArray();
553}
554
555
556bool Object::IsHashTable() {
557 return Object::IsHeapObject()
558 && HeapObject::cast(this)->map() == Heap::hash_table_map();
559}
560
561
562bool Object::IsDictionary() {
563 return IsHashTable() && this != Heap::symbol_table();
564}
565
566
567bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000568 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000569}
570
571
ager@chromium.orgac091b72010-05-05 07:34:42 +0000572bool Object::IsJSFunctionResultCache() {
573 if (!IsFixedArray()) return false;
574 FixedArray* self = FixedArray::cast(this);
575 int length = self->length();
576 if (length < JSFunctionResultCache::kEntriesIndex) return false;
577 if ((length - JSFunctionResultCache::kEntriesIndex)
578 % JSFunctionResultCache::kEntrySize != 0) {
579 return false;
580 }
581#ifdef DEBUG
582 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
583#endif
584 return true;
585}
586
587
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000588bool Object::IsCompilationCacheTable() {
589 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000590}
591
592
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000593bool Object::IsCodeCacheHashTable() {
594 return IsHashTable();
595}
596
597
ager@chromium.org236ad962008-09-25 09:45:57 +0000598bool Object::IsMapCache() {
599 return IsHashTable();
600}
601
602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603bool Object::IsPrimitive() {
604 return IsOddball() || IsNumber() || IsString();
605}
606
607
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000608bool Object::IsJSGlobalProxy() {
609 bool result = IsHeapObject() &&
610 (HeapObject::cast(this)->map()->instance_type() ==
611 JS_GLOBAL_PROXY_TYPE);
612 ASSERT(!result || IsAccessCheckNeeded());
613 return result;
614}
615
616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000618 if (!IsHeapObject()) return false;
619
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000620 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000621 return type == JS_GLOBAL_OBJECT_TYPE ||
622 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
626bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627 return IsHeapObject() &&
628 (HeapObject::cast(this)->map()->instance_type() ==
629 JS_GLOBAL_OBJECT_TYPE);
630}
631
632
633bool Object::IsJSBuiltinsObject() {
634 return IsHeapObject() &&
635 (HeapObject::cast(this)->map()->instance_type() ==
636 JS_BUILTINS_OBJECT_TYPE);
637}
638
639
640bool Object::IsUndetectableObject() {
641 return IsHeapObject()
642 && HeapObject::cast(this)->map()->is_undetectable();
643}
644
645
646bool Object::IsAccessCheckNeeded() {
647 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000648 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649}
650
651
652bool Object::IsStruct() {
653 if (!IsHeapObject()) return false;
654 switch (HeapObject::cast(this)->map()->instance_type()) {
655#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
656 STRUCT_LIST(MAKE_STRUCT_CASE)
657#undef MAKE_STRUCT_CASE
658 default: return false;
659 }
660}
661
662
663#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
664 bool Object::Is##Name() { \
665 return Object::IsHeapObject() \
666 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
667 }
668 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
669#undef MAKE_STRUCT_PREDICATE
670
671
672bool Object::IsUndefined() {
673 return this == Heap::undefined_value();
674}
675
676
677bool Object::IsTheHole() {
678 return this == Heap::the_hole_value();
679}
680
681
682bool Object::IsNull() {
683 return this == Heap::null_value();
684}
685
686
687bool Object::IsTrue() {
688 return this == Heap::true_value();
689}
690
691
692bool Object::IsFalse() {
693 return this == Heap::false_value();
694}
695
696
697double Object::Number() {
698 ASSERT(IsNumber());
699 return IsSmi()
700 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
701 : reinterpret_cast<HeapNumber*>(this)->value();
702}
703
704
705
706Object* Object::ToSmi() {
707 if (IsSmi()) return this;
708 if (IsHeapNumber()) {
709 double value = HeapNumber::cast(this)->value();
710 int int_value = FastD2I(value);
711 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
712 return Smi::FromInt(int_value);
713 }
714 }
715 return Failure::Exception();
716}
717
718
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000719bool Object::HasSpecificClassOf(String* name) {
720 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
721}
722
723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724Object* Object::GetElement(uint32_t index) {
725 return GetElementWithReceiver(this, index);
726}
727
728
729Object* Object::GetProperty(String* key) {
730 PropertyAttributes attributes;
731 return GetPropertyWithReceiver(this, key, &attributes);
732}
733
734
735Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
736 return GetPropertyWithReceiver(this, key, attributes);
737}
738
739
740#define FIELD_ADDR(p, offset) \
741 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
742
743#define READ_FIELD(p, offset) \
744 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
745
746#define WRITE_FIELD(p, offset, value) \
747 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
748
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000749
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750#define WRITE_BARRIER(object, offset) \
751 Heap::RecordWrite(object->address(), offset);
752
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000753// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000754// write due to the assert validating the written value.
755#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
756 if (mode == UPDATE_WRITE_BARRIER) { \
757 Heap::RecordWrite(object->address(), offset); \
758 } else { \
759 ASSERT(mode == SKIP_WRITE_BARRIER); \
760 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000761 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
762 Page::IsRSetSet(object->address(), offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000763 }
764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765#define READ_DOUBLE_FIELD(p, offset) \
766 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
767
768#define WRITE_DOUBLE_FIELD(p, offset, value) \
769 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
770
771#define READ_INT_FIELD(p, offset) \
772 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
773
774#define WRITE_INT_FIELD(p, offset, value) \
775 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
776
ager@chromium.org3e875802009-06-29 08:26:34 +0000777#define READ_INTPTR_FIELD(p, offset) \
778 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
779
780#define WRITE_INTPTR_FIELD(p, offset, value) \
781 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
782
ager@chromium.org7c537e22008-10-16 08:43:32 +0000783#define READ_UINT32_FIELD(p, offset) \
784 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
785
786#define WRITE_UINT32_FIELD(p, offset, value) \
787 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789#define READ_SHORT_FIELD(p, offset) \
790 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
791
792#define WRITE_SHORT_FIELD(p, offset, value) \
793 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
794
795#define READ_BYTE_FIELD(p, offset) \
796 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
797
798#define WRITE_BYTE_FIELD(p, offset, value) \
799 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
800
801
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000802Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
803 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806
807int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000808 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
812Smi* Smi::FromInt(int value) {
813 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000814 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000815 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000816 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000817 return reinterpret_cast<Smi*>(tagged_value);
818}
819
820
821Smi* Smi::FromIntptr(intptr_t value) {
822 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000823 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
824 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825}
826
827
828Failure::Type Failure::type() const {
829 return static_cast<Type>(value() & kFailureTypeTagMask);
830}
831
832
833bool Failure::IsInternalError() const {
834 return type() == INTERNAL_ERROR;
835}
836
837
838bool Failure::IsOutOfMemoryException() const {
839 return type() == OUT_OF_MEMORY_EXCEPTION;
840}
841
842
843int Failure::requested() const {
844 const int kShiftBits =
845 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
846 STATIC_ASSERT(kShiftBits >= 0);
847 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000848 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000849}
850
851
852AllocationSpace Failure::allocation_space() const {
853 ASSERT_EQ(RETRY_AFTER_GC, type());
854 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
855 & kSpaceTagMask);
856}
857
858
859Failure* Failure::InternalError() {
860 return Construct(INTERNAL_ERROR);
861}
862
863
864Failure* Failure::Exception() {
865 return Construct(EXCEPTION);
866}
867
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000869Failure* Failure::OutOfMemoryException() {
870 return Construct(OUT_OF_MEMORY_EXCEPTION);
871}
872
873
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000875 return static_cast<intptr_t>(
876 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877}
878
879
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000880Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000881 // Assert that the space encoding fits in the three bytes allotted for it.
882 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000883 uintptr_t requested =
884 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
885 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000886 if (((requested << tag_bits) >> tag_bits) != requested) {
887 // No room for entire requested size in the bits. Round down to
888 // maximally representable size.
889 requested = static_cast<intptr_t>(
890 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
891 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000892 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000893 return Construct(RETRY_AFTER_GC, value);
894}
895
896
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000897Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000898 uintptr_t info =
899 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000900 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000901 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902}
903
904
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000905bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906#ifdef DEBUG
907 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
908#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000909
910#ifdef V8_TARGET_ARCH_X64
911 // To be representable as a long smi, the value must be a 32-bit integer.
912 bool result = (value == static_cast<int32_t>(value));
913#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000914 // To be representable as an tagged small integer, the two
915 // most-significant bits of 'value' must be either 00 or 11 due to
916 // sign-extension. To check this we add 01 to the two
917 // most-significant bits, and check if the most-significant bit is 0
918 //
919 // CAUTION: The original code below:
920 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
921 // may lead to incorrect results according to the C language spec, and
922 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
923 // compiler may produce undefined results in case of signed integer
924 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000925 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000926#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000927 ASSERT(result == in_range);
928 return result;
929}
930
931
kasper.lund7276f142008-07-30 08:49:36 +0000932MapWord MapWord::FromMap(Map* map) {
933 return MapWord(reinterpret_cast<uintptr_t>(map));
934}
935
936
937Map* MapWord::ToMap() {
938 return reinterpret_cast<Map*>(value_);
939}
940
941
942bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000943 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000944}
945
946
947MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000948 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
949 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000950}
951
952
953HeapObject* MapWord::ToForwardingAddress() {
954 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000955 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000956}
957
958
959bool MapWord::IsMarked() {
960 return (value_ & kMarkingMask) == 0;
961}
962
963
964void MapWord::SetMark() {
965 value_ &= ~kMarkingMask;
966}
967
968
969void MapWord::ClearMark() {
970 value_ |= kMarkingMask;
971}
972
973
974bool MapWord::IsOverflowed() {
975 return (value_ & kOverflowMask) != 0;
976}
977
978
979void MapWord::SetOverflow() {
980 value_ |= kOverflowMask;
981}
982
983
984void MapWord::ClearOverflow() {
985 value_ &= ~kOverflowMask;
986}
987
988
989MapWord MapWord::EncodeAddress(Address map_address, int offset) {
990 // Offset is the distance in live bytes from the first live object in the
991 // same page. The offset between two objects in the same page should not
992 // exceed the object area size of a page.
993 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
994
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000995 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000996 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
997
998 Page* map_page = Page::FromAddress(map_address);
999 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1000
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001001 uintptr_t map_page_offset =
1002 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001003
1004 uintptr_t encoding =
1005 (compact_offset << kForwardingOffsetShift) |
1006 (map_page_offset << kMapPageOffsetShift) |
1007 (map_page->mc_page_index << kMapPageIndexShift);
1008 return MapWord(encoding);
1009}
1010
1011
1012Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001013 int map_page_index =
1014 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001015 ASSERT_MAP_PAGE_INDEX(map_page_index);
1016
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001017 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001018 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1019 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001020
1021 return (map_space->PageAddress(map_page_index) + map_page_offset);
1022}
1023
1024
1025int MapWord::DecodeOffset() {
1026 // The offset field is represented in the kForwardingOffsetBits
1027 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001028 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1029 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1030 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001031}
1032
1033
1034MapWord MapWord::FromEncodedAddress(Address address) {
1035 return MapWord(reinterpret_cast<uintptr_t>(address));
1036}
1037
1038
1039Address MapWord::ToEncodedAddress() {
1040 return reinterpret_cast<Address>(value_);
1041}
1042
1043
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044#ifdef DEBUG
1045void HeapObject::VerifyObjectField(int offset) {
1046 VerifyPointer(READ_FIELD(this, offset));
1047}
1048#endif
1049
1050
1051Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001052 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053}
1054
1055
1056void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001057 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058}
1059
1060
kasper.lund7276f142008-07-30 08:49:36 +00001061MapWord HeapObject::map_word() {
1062 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1063}
1064
1065
1066void HeapObject::set_map_word(MapWord map_word) {
1067 // WRITE_FIELD does not update the remembered set, but there is no need
1068 // here.
1069 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1070}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001071
1072
1073HeapObject* HeapObject::FromAddress(Address address) {
1074 ASSERT_TAG_ALIGNED(address);
1075 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1076}
1077
1078
1079Address HeapObject::address() {
1080 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1081}
1082
1083
1084int HeapObject::Size() {
1085 return SizeFromMap(map());
1086}
1087
1088
1089void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1090 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1091 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1092}
1093
1094
1095void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1096 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1097}
1098
1099
kasper.lund7276f142008-07-30 08:49:36 +00001100bool HeapObject::IsMarked() {
1101 return map_word().IsMarked();
1102}
1103
1104
1105void HeapObject::SetMark() {
1106 ASSERT(!IsMarked());
1107 MapWord first_word = map_word();
1108 first_word.SetMark();
1109 set_map_word(first_word);
1110}
1111
1112
1113void HeapObject::ClearMark() {
1114 ASSERT(IsMarked());
1115 MapWord first_word = map_word();
1116 first_word.ClearMark();
1117 set_map_word(first_word);
1118}
1119
1120
1121bool HeapObject::IsOverflowed() {
1122 return map_word().IsOverflowed();
1123}
1124
1125
1126void HeapObject::SetOverflow() {
1127 MapWord first_word = map_word();
1128 first_word.SetOverflow();
1129 set_map_word(first_word);
1130}
1131
1132
1133void HeapObject::ClearOverflow() {
1134 ASSERT(IsOverflowed());
1135 MapWord first_word = map_word();
1136 first_word.ClearOverflow();
1137 set_map_word(first_word);
1138}
1139
1140
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001141double HeapNumber::value() {
1142 return READ_DOUBLE_FIELD(this, kValueOffset);
1143}
1144
1145
1146void HeapNumber::set_value(double value) {
1147 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1148}
1149
1150
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001151int HeapNumber::get_exponent() {
1152 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1153 kExponentShift) - kExponentBias;
1154}
1155
1156
1157int HeapNumber::get_sign() {
1158 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001163
1164
1165Array* JSObject::elements() {
1166 Object* array = READ_FIELD(this, kElementsOffset);
1167 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001168 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1169 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001170 return reinterpret_cast<Array*>(array);
1171}
1172
1173
1174void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1175 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001176 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1177 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001178 WRITE_FIELD(this, kElementsOffset, value);
1179 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1180}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181
1182
1183void JSObject::initialize_properties() {
1184 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1185 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1186}
1187
1188
1189void JSObject::initialize_elements() {
1190 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1191 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1192}
1193
1194
1195ACCESSORS(Oddball, to_string, String, kToStringOffset)
1196ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1197
1198
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001199Object* JSGlobalPropertyCell::value() {
1200 return READ_FIELD(this, kValueOffset);
1201}
1202
1203
1204void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1205 // The write barrier is not used for global property cells.
1206 ASSERT(!val->IsJSGlobalPropertyCell());
1207 WRITE_FIELD(this, kValueOffset, val);
1208}
1209
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001212 InstanceType type = map()->instance_type();
1213 // Check for the most common kind of JavaScript object before
1214 // falling into the generic switch. This speeds up the internal
1215 // field operations considerably on average.
1216 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1217 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001218 case JS_GLOBAL_PROXY_TYPE:
1219 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220 case JS_GLOBAL_OBJECT_TYPE:
1221 return JSGlobalObject::kSize;
1222 case JS_BUILTINS_OBJECT_TYPE:
1223 return JSBuiltinsObject::kSize;
1224 case JS_FUNCTION_TYPE:
1225 return JSFunction::kSize;
1226 case JS_VALUE_TYPE:
1227 return JSValue::kSize;
1228 case JS_ARRAY_TYPE:
1229 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001230 case JS_REGEXP_TYPE:
1231 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001232 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233 return JSObject::kHeaderSize;
1234 default:
1235 UNREACHABLE();
1236 return 0;
1237 }
1238}
1239
1240
1241int JSObject::GetInternalFieldCount() {
1242 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001243 // Make sure to adjust for the number of in-object properties. These
1244 // properties do contribute to the size, but are not internal fields.
1245 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1246 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001247}
1248
1249
1250Object* JSObject::GetInternalField(int index) {
1251 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001252 // Internal objects do follow immediately after the header, whereas in-object
1253 // properties are at the end of the object. Therefore there is no need
1254 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1256}
1257
1258
1259void JSObject::SetInternalField(int index, Object* value) {
1260 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001261 // Internal objects do follow immediately after the header, whereas in-object
1262 // properties are at the end of the object. Therefore there is no need
1263 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001264 int offset = GetHeaderSize() + (kPointerSize * index);
1265 WRITE_FIELD(this, offset, value);
1266 WRITE_BARRIER(this, offset);
1267}
1268
1269
ager@chromium.org7c537e22008-10-16 08:43:32 +00001270// Access fast-case object properties at index. The use of these routines
1271// is needed to correctly distinguish between properties stored in-object and
1272// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001273Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001274 // Adjust for the number of properties stored in the object.
1275 index -= map()->inobject_properties();
1276 if (index < 0) {
1277 int offset = map()->instance_size() + (index * kPointerSize);
1278 return READ_FIELD(this, offset);
1279 } else {
1280 ASSERT(index < properties()->length());
1281 return properties()->get(index);
1282 }
1283}
1284
1285
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001286Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001287 // Adjust for the number of properties stored in the object.
1288 index -= map()->inobject_properties();
1289 if (index < 0) {
1290 int offset = map()->instance_size() + (index * kPointerSize);
1291 WRITE_FIELD(this, offset, value);
1292 WRITE_BARRIER(this, offset);
1293 } else {
1294 ASSERT(index < properties()->length());
1295 properties()->set(index, value);
1296 }
1297 return value;
1298}
1299
1300
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001301Object* JSObject::InObjectPropertyAt(int index) {
1302 // Adjust for the number of properties stored in the object.
1303 index -= map()->inobject_properties();
1304 ASSERT(index < 0);
1305 int offset = map()->instance_size() + (index * kPointerSize);
1306 return READ_FIELD(this, offset);
1307}
1308
1309
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001310Object* JSObject::InObjectPropertyAtPut(int index,
1311 Object* value,
1312 WriteBarrierMode mode) {
1313 // Adjust for the number of properties stored in the object.
1314 index -= map()->inobject_properties();
1315 ASSERT(index < 0);
1316 int offset = map()->instance_size() + (index * kPointerSize);
1317 WRITE_FIELD(this, offset, value);
1318 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1319 return value;
1320}
1321
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001325 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001326 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001327 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328 }
1329}
1330
1331
1332void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001333 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001334 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001335 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001336 }
1337}
1338
1339
1340bool JSObject::HasFastProperties() {
1341 return !properties()->IsDictionary();
1342}
1343
1344
1345bool Array::IndexFromObject(Object* object, uint32_t* index) {
1346 if (object->IsSmi()) {
1347 int value = Smi::cast(object)->value();
1348 if (value < 0) return false;
1349 *index = value;
1350 return true;
1351 }
1352 if (object->IsHeapNumber()) {
1353 double value = HeapNumber::cast(object)->value();
1354 uint32_t uint_value = static_cast<uint32_t>(value);
1355 if (value == static_cast<double>(uint_value)) {
1356 *index = uint_value;
1357 return true;
1358 }
1359 }
1360 return false;
1361}
1362
1363
1364bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1365 if (!this->IsJSValue()) return false;
1366
1367 JSValue* js_value = JSValue::cast(this);
1368 if (!js_value->value()->IsString()) return false;
1369
1370 String* str = String::cast(js_value->value());
1371 if (index >= (uint32_t)str->length()) return false;
1372
1373 return true;
1374}
1375
1376
1377Object* FixedArray::get(int index) {
1378 ASSERT(index >= 0 && index < this->length());
1379 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1380}
1381
1382
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001383void FixedArray::set(int index, Smi* value) {
1384 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1385 int offset = kHeaderSize + index * kPointerSize;
1386 WRITE_FIELD(this, offset, value);
1387}
1388
1389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001390void FixedArray::set(int index, Object* value) {
1391 ASSERT(index >= 0 && index < this->length());
1392 int offset = kHeaderSize + index * kPointerSize;
1393 WRITE_FIELD(this, offset, value);
1394 WRITE_BARRIER(this, offset);
1395}
1396
1397
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001398WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001399 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1400 return UPDATE_WRITE_BARRIER;
1401}
1402
1403
1404void FixedArray::set(int index,
1405 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001406 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 ASSERT(index >= 0 && index < this->length());
1408 int offset = kHeaderSize + index * kPointerSize;
1409 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001410 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411}
1412
1413
1414void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1415 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001416 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1418}
1419
1420
1421void FixedArray::set_undefined(int index) {
1422 ASSERT(index >= 0 && index < this->length());
1423 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1424 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1425 Heap::undefined_value());
1426}
1427
1428
ager@chromium.org236ad962008-09-25 09:45:57 +00001429void FixedArray::set_null(int index) {
1430 ASSERT(index >= 0 && index < this->length());
1431 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1432 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1433}
1434
1435
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436void FixedArray::set_the_hole(int index) {
1437 ASSERT(index >= 0 && index < this->length());
1438 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1439 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1440}
1441
1442
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001443Object** FixedArray::data_start() {
1444 return HeapObject::RawField(this, kHeaderSize);
1445}
1446
1447
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001448bool DescriptorArray::IsEmpty() {
1449 ASSERT(this == Heap::empty_descriptor_array() ||
1450 this->length() > 2);
1451 return this == Heap::empty_descriptor_array();
1452}
1453
1454
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1456 Object* tmp = array->get(first);
1457 fast_set(array, first, array->get(second));
1458 fast_set(array, second, tmp);
1459}
1460
1461
1462int DescriptorArray::Search(String* name) {
1463 SLOW_ASSERT(IsSortedNoDuplicates());
1464
1465 // Check for empty descriptor array.
1466 int nof = number_of_descriptors();
1467 if (nof == 0) return kNotFound;
1468
1469 // Fast case: do linear search for small arrays.
1470 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001471 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001472 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 }
1474
1475 // Slow case: perform binary search.
1476 return BinarySearch(name, 0, nof - 1);
1477}
1478
1479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480String* DescriptorArray::GetKey(int descriptor_number) {
1481 ASSERT(descriptor_number < number_of_descriptors());
1482 return String::cast(get(ToKeyIndex(descriptor_number)));
1483}
1484
1485
1486Object* DescriptorArray::GetValue(int descriptor_number) {
1487 ASSERT(descriptor_number < number_of_descriptors());
1488 return GetContentArray()->get(ToValueIndex(descriptor_number));
1489}
1490
1491
1492Smi* DescriptorArray::GetDetails(int descriptor_number) {
1493 ASSERT(descriptor_number < number_of_descriptors());
1494 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1495}
1496
1497
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001498PropertyType DescriptorArray::GetType(int descriptor_number) {
1499 ASSERT(descriptor_number < number_of_descriptors());
1500 return PropertyDetails(GetDetails(descriptor_number)).type();
1501}
1502
1503
1504int DescriptorArray::GetFieldIndex(int descriptor_number) {
1505 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1506}
1507
1508
1509JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1510 return JSFunction::cast(GetValue(descriptor_number));
1511}
1512
1513
1514Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1515 ASSERT(GetType(descriptor_number) == CALLBACKS);
1516 return GetValue(descriptor_number);
1517}
1518
1519
1520AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1521 ASSERT(GetType(descriptor_number) == CALLBACKS);
1522 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1523 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1524}
1525
1526
1527bool DescriptorArray::IsProperty(int descriptor_number) {
1528 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1529}
1530
1531
1532bool DescriptorArray::IsTransition(int descriptor_number) {
1533 PropertyType t = GetType(descriptor_number);
1534 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1535}
1536
1537
1538bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1539 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1540}
1541
1542
1543bool DescriptorArray::IsDontEnum(int descriptor_number) {
1544 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1545}
1546
1547
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1549 desc->Init(GetKey(descriptor_number),
1550 GetValue(descriptor_number),
1551 GetDetails(descriptor_number));
1552}
1553
1554
1555void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1556 // Range check.
1557 ASSERT(descriptor_number < number_of_descriptors());
1558
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001559 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1561 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1562
1563 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1564 FixedArray* content_array = GetContentArray();
1565 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1566 fast_set(content_array, ToDetailsIndex(descriptor_number),
1567 desc->GetDetails().AsSmi());
1568}
1569
1570
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001571void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1572 Descriptor desc;
1573 src->Get(src_index, &desc);
1574 Set(index, &desc);
1575}
1576
1577
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578void DescriptorArray::Swap(int first, int second) {
1579 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1580 FixedArray* content_array = GetContentArray();
1581 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1582 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1583}
1584
1585
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001586bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001587 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001588 if (!max_index_object->IsSmi()) return false;
1589 return 0 !=
1590 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1591}
1592
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001593uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001595 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 if (!max_index_object->IsSmi()) return 0;
1597 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1598 return value >> kRequiresSlowElementsTagSize;
1599}
1600
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001601void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001602 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001603}
1604
1605
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001606// ------------------------------------
1607// Cast operations
1608
1609
1610CAST_ACCESSOR(FixedArray)
1611CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001613CAST_ACCESSOR(JSFunctionResultCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001614CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001615CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001616CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617CAST_ACCESSOR(String)
1618CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001619CAST_ACCESSOR(SeqAsciiString)
1620CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001621CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622CAST_ACCESSOR(ExternalString)
1623CAST_ACCESSOR(ExternalAsciiString)
1624CAST_ACCESSOR(ExternalTwoByteString)
1625CAST_ACCESSOR(JSObject)
1626CAST_ACCESSOR(Smi)
1627CAST_ACCESSOR(Failure)
1628CAST_ACCESSOR(HeapObject)
1629CAST_ACCESSOR(HeapNumber)
1630CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001631CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632CAST_ACCESSOR(SharedFunctionInfo)
1633CAST_ACCESSOR(Map)
1634CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001635CAST_ACCESSOR(GlobalObject)
1636CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637CAST_ACCESSOR(JSGlobalObject)
1638CAST_ACCESSOR(JSBuiltinsObject)
1639CAST_ACCESSOR(Code)
1640CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001641CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001642CAST_ACCESSOR(Proxy)
1643CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001644CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001645CAST_ACCESSOR(ExternalArray)
1646CAST_ACCESSOR(ExternalByteArray)
1647CAST_ACCESSOR(ExternalUnsignedByteArray)
1648CAST_ACCESSOR(ExternalShortArray)
1649CAST_ACCESSOR(ExternalUnsignedShortArray)
1650CAST_ACCESSOR(ExternalIntArray)
1651CAST_ACCESSOR(ExternalUnsignedIntArray)
1652CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653CAST_ACCESSOR(Struct)
1654
1655
1656#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1657 STRUCT_LIST(MAKE_STRUCT_CAST)
1658#undef MAKE_STRUCT_CAST
1659
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001660
1661template <typename Shape, typename Key>
1662HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001663 ASSERT(obj->IsHashTable());
1664 return reinterpret_cast<HashTable*>(obj);
1665}
1666
1667
1668INT_ACCESSORS(Array, length, kLengthOffset)
1669
1670
ager@chromium.orgac091b72010-05-05 07:34:42 +00001671SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001672
1673
1674uint32_t String::hash_field() {
1675 return READ_UINT32_FIELD(this, kHashFieldOffset);
1676}
1677
1678
1679void String::set_hash_field(uint32_t value) {
1680 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1681}
1682
1683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001684bool String::Equals(String* other) {
1685 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001686 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1687 return false;
1688 }
1689 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690}
1691
1692
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001693Object* String::TryFlatten(PretenureFlag pretenure) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001694 // We don't need to flatten strings that are already flat. Since this code
1695 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001696 if (IsFlat()) return this;
1697 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698}
1699
1700
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001701uint16_t String::Get(int index) {
1702 ASSERT(index >= 0 && index < length());
1703 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001704 case kSeqStringTag | kAsciiStringTag:
1705 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1706 case kSeqStringTag | kTwoByteStringTag:
1707 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1708 case kConsStringTag | kAsciiStringTag:
1709 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001711 case kExternalStringTag | kAsciiStringTag:
1712 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1713 case kExternalStringTag | kTwoByteStringTag:
1714 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 default:
1716 break;
1717 }
1718
1719 UNREACHABLE();
1720 return 0;
1721}
1722
1723
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001724void String::Set(int index, uint16_t value) {
1725 ASSERT(index >= 0 && index < length());
1726 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727
ager@chromium.org5ec48922009-05-05 07:25:34 +00001728 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001729 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1730 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731}
1732
1733
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001734bool String::IsFlat() {
1735 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001736 case kConsStringTag: {
1737 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001738 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001739 return second->length() == 0;
1740 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001741 default:
1742 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743 }
1744}
1745
1746
ager@chromium.org7c537e22008-10-16 08:43:32 +00001747uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 ASSERT(index >= 0 && index < length());
1749 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1750}
1751
1752
ager@chromium.org7c537e22008-10-16 08:43:32 +00001753void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1755 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1756 static_cast<byte>(value));
1757}
1758
1759
ager@chromium.org7c537e22008-10-16 08:43:32 +00001760Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761 return FIELD_ADDR(this, kHeaderSize);
1762}
1763
1764
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001765char* SeqAsciiString::GetChars() {
1766 return reinterpret_cast<char*>(GetCharsAddress());
1767}
1768
1769
ager@chromium.org7c537e22008-10-16 08:43:32 +00001770Address SeqTwoByteString::GetCharsAddress() {
1771 return FIELD_ADDR(this, kHeaderSize);
1772}
1773
1774
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001775uc16* SeqTwoByteString::GetChars() {
1776 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1777}
1778
1779
ager@chromium.org7c537e22008-10-16 08:43:32 +00001780uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 ASSERT(index >= 0 && index < length());
1782 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1783}
1784
1785
ager@chromium.org7c537e22008-10-16 08:43:32 +00001786void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 ASSERT(index >= 0 && index < length());
1788 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1789}
1790
1791
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001792int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001793 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794}
1795
1796
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001797int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001798 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799}
1800
1801
ager@chromium.org870a0b62008-11-04 11:43:05 +00001802String* ConsString::first() {
1803 return String::cast(READ_FIELD(this, kFirstOffset));
1804}
1805
1806
1807Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 return READ_FIELD(this, kFirstOffset);
1809}
1810
1811
ager@chromium.org870a0b62008-11-04 11:43:05 +00001812void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001814 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815}
1816
1817
ager@chromium.org870a0b62008-11-04 11:43:05 +00001818String* ConsString::second() {
1819 return String::cast(READ_FIELD(this, kSecondOffset));
1820}
1821
1822
1823Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 return READ_FIELD(this, kSecondOffset);
1825}
1826
1827
ager@chromium.org870a0b62008-11-04 11:43:05 +00001828void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001830 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831}
1832
1833
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001834ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1835 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1836}
1837
1838
1839void ExternalAsciiString::set_resource(
1840 ExternalAsciiString::Resource* resource) {
1841 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1842}
1843
1844
1845ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1846 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1847}
1848
1849
1850void ExternalTwoByteString::set_resource(
1851 ExternalTwoByteString::Resource* resource) {
1852 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1853}
1854
1855
ager@chromium.orgac091b72010-05-05 07:34:42 +00001856void JSFunctionResultCache::MakeZeroSize() {
1857 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1858 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1859}
1860
1861
1862void JSFunctionResultCache::Clear() {
1863 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1864 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1865 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1866 MakeZeroSize();
1867}
1868
1869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870byte ByteArray::get(int index) {
1871 ASSERT(index >= 0 && index < this->length());
1872 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1873}
1874
1875
1876void ByteArray::set(int index, byte value) {
1877 ASSERT(index >= 0 && index < this->length());
1878 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1879}
1880
1881
1882int ByteArray::get_int(int index) {
1883 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1884 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1885}
1886
1887
1888ByteArray* ByteArray::FromDataStartAddress(Address address) {
1889 ASSERT_TAG_ALIGNED(address);
1890 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1891}
1892
1893
1894Address ByteArray::GetDataStartAddress() {
1895 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1896}
1897
1898
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001899uint8_t* PixelArray::external_pointer() {
1900 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1901 return reinterpret_cast<uint8_t*>(ptr);
1902}
1903
1904
1905void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1906 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1907 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1908}
1909
1910
1911uint8_t PixelArray::get(int index) {
1912 ASSERT((index >= 0) && (index < this->length()));
1913 uint8_t* ptr = external_pointer();
1914 return ptr[index];
1915}
1916
1917
1918void PixelArray::set(int index, uint8_t value) {
1919 ASSERT((index >= 0) && (index < this->length()));
1920 uint8_t* ptr = external_pointer();
1921 ptr[index] = value;
1922}
1923
1924
ager@chromium.org3811b432009-10-28 14:53:37 +00001925void* ExternalArray::external_pointer() {
1926 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1927 return reinterpret_cast<void*>(ptr);
1928}
1929
1930
1931void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1932 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1933 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1934}
1935
1936
1937int8_t ExternalByteArray::get(int index) {
1938 ASSERT((index >= 0) && (index < this->length()));
1939 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1940 return ptr[index];
1941}
1942
1943
1944void ExternalByteArray::set(int index, int8_t value) {
1945 ASSERT((index >= 0) && (index < this->length()));
1946 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1947 ptr[index] = value;
1948}
1949
1950
1951uint8_t ExternalUnsignedByteArray::get(int index) {
1952 ASSERT((index >= 0) && (index < this->length()));
1953 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1954 return ptr[index];
1955}
1956
1957
1958void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1959 ASSERT((index >= 0) && (index < this->length()));
1960 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1961 ptr[index] = value;
1962}
1963
1964
1965int16_t ExternalShortArray::get(int index) {
1966 ASSERT((index >= 0) && (index < this->length()));
1967 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1968 return ptr[index];
1969}
1970
1971
1972void ExternalShortArray::set(int index, int16_t value) {
1973 ASSERT((index >= 0) && (index < this->length()));
1974 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1975 ptr[index] = value;
1976}
1977
1978
1979uint16_t ExternalUnsignedShortArray::get(int index) {
1980 ASSERT((index >= 0) && (index < this->length()));
1981 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1982 return ptr[index];
1983}
1984
1985
1986void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1987 ASSERT((index >= 0) && (index < this->length()));
1988 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1989 ptr[index] = value;
1990}
1991
1992
1993int32_t ExternalIntArray::get(int index) {
1994 ASSERT((index >= 0) && (index < this->length()));
1995 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1996 return ptr[index];
1997}
1998
1999
2000void ExternalIntArray::set(int index, int32_t value) {
2001 ASSERT((index >= 0) && (index < this->length()));
2002 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2003 ptr[index] = value;
2004}
2005
2006
2007uint32_t ExternalUnsignedIntArray::get(int index) {
2008 ASSERT((index >= 0) && (index < this->length()));
2009 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2010 return ptr[index];
2011}
2012
2013
2014void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2015 ASSERT((index >= 0) && (index < this->length()));
2016 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2017 ptr[index] = value;
2018}
2019
2020
2021float ExternalFloatArray::get(int index) {
2022 ASSERT((index >= 0) && (index < this->length()));
2023 float* ptr = static_cast<float*>(external_pointer());
2024 return ptr[index];
2025}
2026
2027
2028void ExternalFloatArray::set(int index, float value) {
2029 ASSERT((index >= 0) && (index < this->length()));
2030 float* ptr = static_cast<float*>(external_pointer());
2031 ptr[index] = value;
2032}
2033
2034
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2037}
2038
2039
2040int Map::inobject_properties() {
2041 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042}
2043
2044
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002045int Map::pre_allocated_property_fields() {
2046 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2047}
2048
2049
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002050int HeapObject::SizeFromMap(Map* map) {
2051 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002052 // Only inline the most frequent cases.
2053 if (instance_type == JS_OBJECT_TYPE ||
2054 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2055 (kStringTag | kConsStringTag) ||
2056 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057 if (instance_type == FIXED_ARRAY_TYPE) {
2058 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2059 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002060 if (instance_type == BYTE_ARRAY_TYPE) {
2061 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2062 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 // Otherwise do the general size computation.
2064 return SlowSizeFromMap(map);
2065}
2066
2067
2068void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002069 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002070 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002071 ASSERT(0 <= value && value < 256);
2072 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2073}
2074
2075
ager@chromium.org7c537e22008-10-16 08:43:32 +00002076void Map::set_inobject_properties(int value) {
2077 ASSERT(0 <= value && value < 256);
2078 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2079}
2080
2081
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002082void Map::set_pre_allocated_property_fields(int value) {
2083 ASSERT(0 <= value && value < 256);
2084 WRITE_BYTE_FIELD(this,
2085 kPreAllocatedPropertyFieldsOffset,
2086 static_cast<byte>(value));
2087}
2088
2089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090InstanceType Map::instance_type() {
2091 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2092}
2093
2094
2095void Map::set_instance_type(InstanceType value) {
2096 ASSERT(0 <= value && value < 256);
2097 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2098}
2099
2100
2101int Map::unused_property_fields() {
2102 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2103}
2104
2105
2106void Map::set_unused_property_fields(int value) {
2107 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2108}
2109
2110
2111byte Map::bit_field() {
2112 return READ_BYTE_FIELD(this, kBitFieldOffset);
2113}
2114
2115
2116void Map::set_bit_field(byte value) {
2117 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2118}
2119
2120
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002121byte Map::bit_field2() {
2122 return READ_BYTE_FIELD(this, kBitField2Offset);
2123}
2124
2125
2126void Map::set_bit_field2(byte value) {
2127 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2128}
2129
2130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131void Map::set_non_instance_prototype(bool value) {
2132 if (value) {
2133 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2134 } else {
2135 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2136 }
2137}
2138
2139
2140bool Map::has_non_instance_prototype() {
2141 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2142}
2143
2144
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002145void Map::set_function_with_prototype(bool value) {
2146 if (value) {
2147 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2148 } else {
2149 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2150 }
2151}
2152
2153
2154bool Map::function_with_prototype() {
2155 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2156}
2157
2158
ager@chromium.org870a0b62008-11-04 11:43:05 +00002159void Map::set_is_access_check_needed(bool access_check_needed) {
2160 if (access_check_needed) {
2161 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2162 } else {
2163 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2164 }
2165}
2166
2167
2168bool Map::is_access_check_needed() {
2169 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2170}
2171
2172
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173Code::Flags Code::flags() {
2174 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2175}
2176
2177
2178void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002179 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180 // Make sure that all call stubs have an arguments count.
2181 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2182 ExtractArgumentsCountFromFlags(flags) >= 0);
2183 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2184}
2185
2186
2187Code::Kind Code::kind() {
2188 return ExtractKindFromFlags(flags());
2189}
2190
2191
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002192InLoopFlag Code::ic_in_loop() {
2193 return ExtractICInLoopFromFlags(flags());
2194}
2195
2196
kasper.lund7276f142008-07-30 08:49:36 +00002197InlineCacheState Code::ic_state() {
2198 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199 // Only allow uninitialized or debugger states for non-IC code
2200 // objects. This is used in the debugger to determine whether or not
2201 // a call to code object has been replaced with a debug break call.
2202 ASSERT(is_inline_cache_stub() ||
2203 result == UNINITIALIZED ||
2204 result == DEBUG_BREAK ||
2205 result == DEBUG_PREPARE_STEP_IN);
2206 return result;
2207}
2208
2209
2210PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002211 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212 return ExtractTypeFromFlags(flags());
2213}
2214
2215
2216int Code::arguments_count() {
2217 ASSERT(is_call_stub() || kind() == STUB);
2218 return ExtractArgumentsCountFromFlags(flags());
2219}
2220
2221
2222CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002223 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002224 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2225 kStubMajorKeyOffset));
2226}
2227
2228
2229void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002230 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002231 ASSERT(0 <= major && major < 256);
2232 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002233}
2234
2235
2236bool Code::is_inline_cache_stub() {
2237 Kind kind = this->kind();
2238 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2239}
2240
2241
2242Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002243 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002244 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002245 PropertyType type,
2246 int argc) {
2247 // Compute the bit mask.
2248 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002249 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002250 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251 bits |= type << kFlagsTypeShift;
2252 bits |= argc << kFlagsArgumentsCountShift;
2253 // Cast to flags and validate result before returning it.
2254 Flags result = static_cast<Flags>(bits);
2255 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002256 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002257 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258 ASSERT(ExtractTypeFromFlags(result) == type);
2259 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2260 return result;
2261}
2262
2263
2264Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2265 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002266 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002268 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269}
2270
2271
2272Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2273 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2274 return static_cast<Kind>(bits);
2275}
2276
2277
kasper.lund7276f142008-07-30 08:49:36 +00002278InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2279 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280 return static_cast<InlineCacheState>(bits);
2281}
2282
2283
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002284InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2285 int bits = (flags & kFlagsICInLoopMask);
2286 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2287}
2288
2289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2291 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2292 return static_cast<PropertyType>(bits);
2293}
2294
2295
2296int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2297 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2298}
2299
2300
2301Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2302 int bits = flags & ~kFlagsTypeMask;
2303 return static_cast<Flags>(bits);
2304}
2305
2306
ager@chromium.org8bb60582008-12-11 12:02:20 +00002307Code* Code::GetCodeFromTargetAddress(Address address) {
2308 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2309 // GetCodeFromTargetAddress might be called when marking objects during mark
2310 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2311 // Code::cast. Code::cast does not work when the object's map is
2312 // marked.
2313 Code* result = reinterpret_cast<Code*>(code);
2314 return result;
2315}
2316
2317
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318Object* Map::prototype() {
2319 return READ_FIELD(this, kPrototypeOffset);
2320}
2321
2322
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002323void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324 ASSERT(value->IsNull() || value->IsJSObject());
2325 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002326 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327}
2328
2329
2330ACCESSORS(Map, instance_descriptors, DescriptorArray,
2331 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002332ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333ACCESSORS(Map, constructor, Object, kConstructorOffset)
2334
2335ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2336ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2337
2338ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2339ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002340ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002342ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343
2344ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2345ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2346ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2347ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2348ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002349ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350
2351ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2352ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2353ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2354
2355ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2356ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2357ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2358ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2359ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2360ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2361
2362ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2363ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2364
2365ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2366ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2367
2368ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2369ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2371 kPropertyAccessorsOffset)
2372ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2373 kPrototypeTemplateOffset)
2374ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2375ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2376 kNamedPropertyHandlerOffset)
2377ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2378 kIndexedPropertyHandlerOffset)
2379ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2380 kInstanceTemplateOffset)
2381ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2382ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2384 kInstanceCallHandlerOffset)
2385ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2386 kAccessCheckInfoOffset)
2387ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2388
2389ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002390ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2391 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392
2393ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2394ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2395
2396ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2397
2398ACCESSORS(Script, source, Object, kSourceOffset)
2399ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002400ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2402ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002403ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002404ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2406ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002407ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002408ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002409ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002410ACCESSORS(Script, eval_from_instructions_offset, Smi,
2411 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002412
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002413#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2415ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2416ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2417ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2418
2419ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2420ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2421ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2422ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002423#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002424
2425ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002426ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2428 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002429ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2431ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002432ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002433ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2434 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002435
2436BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2437 kHiddenPrototypeBit)
2438BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2439BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2440 kNeedsAccessCheckBit)
2441BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2442 kIsExpressionBit)
2443BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2444 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002445BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002446 has_only_simple_this_property_assignments,
2447 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002448BOOL_ACCESSORS(SharedFunctionInfo,
2449 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002450 try_full_codegen,
2451 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002452
2453INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2454INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2455 kFormalParameterCountOffset)
2456INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2457 kExpectedNofPropertiesOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002458INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2460 kStartPositionAndTypeOffset)
2461INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2462INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2463 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002464INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2465 kCompilerHintsOffset)
2466INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2467 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468
2469
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002470ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2471ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2472
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002473bool Script::HasValidSource() {
2474 Object* src = this->source();
2475 if (!src->IsString()) return true;
2476 String* src_str = String::cast(src);
2477 if (!StringShape(src_str).IsExternal()) return true;
2478 if (src_str->IsAsciiRepresentation()) {
2479 return ExternalAsciiString::cast(src)->resource() != NULL;
2480 } else if (src_str->IsTwoByteRepresentation()) {
2481 return ExternalTwoByteString::cast(src)->resource() != NULL;
2482 }
2483 return true;
2484}
2485
2486
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002487void SharedFunctionInfo::DontAdaptArguments() {
2488 ASSERT(code()->kind() == Code::BUILTIN);
2489 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2490}
2491
2492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002493int SharedFunctionInfo::start_position() {
2494 return start_position_and_type() >> kStartPositionShift;
2495}
2496
2497
2498void SharedFunctionInfo::set_start_position(int start_position) {
2499 set_start_position_and_type((start_position << kStartPositionShift)
2500 | (start_position_and_type() & ~kStartPositionMask));
2501}
2502
2503
2504Code* SharedFunctionInfo::code() {
2505 return Code::cast(READ_FIELD(this, kCodeOffset));
2506}
2507
2508
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002509void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002510 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002511 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002512}
2513
2514
2515bool SharedFunctionInfo::is_compiled() {
2516 // TODO(1242782): Create a code kind for uncompiled code.
2517 return code()->kind() != Code::STUB;
2518}
2519
2520
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002521bool SharedFunctionInfo::IsApiFunction() {
2522 return function_data()->IsFunctionTemplateInfo();
2523}
2524
2525
2526FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2527 ASSERT(IsApiFunction());
2528 return FunctionTemplateInfo::cast(function_data());
2529}
2530
2531
2532bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002533 return function_data()->IsSmi();
2534}
2535
2536
2537int SharedFunctionInfo::custom_call_generator_id() {
2538 ASSERT(HasCustomCallGenerator());
2539 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002540}
2541
2542
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002543bool JSFunction::IsBuiltin() {
2544 return context()->global()->IsJSBuiltinsObject();
2545}
2546
2547
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002548Code* JSFunction::code() {
2549 return shared()->code();
2550}
2551
2552
2553void JSFunction::set_code(Code* value) {
2554 shared()->set_code(value);
2555}
2556
2557
2558Context* JSFunction::context() {
2559 return Context::cast(READ_FIELD(this, kContextOffset));
2560}
2561
2562
2563Object* JSFunction::unchecked_context() {
2564 return READ_FIELD(this, kContextOffset);
2565}
2566
2567
2568void JSFunction::set_context(Object* value) {
2569 ASSERT(value == Heap::undefined_value() || value->IsContext());
2570 WRITE_FIELD(this, kContextOffset, value);
2571 WRITE_BARRIER(this, kContextOffset);
2572}
2573
2574ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2575 kPrototypeOrInitialMapOffset)
2576
2577
2578Map* JSFunction::initial_map() {
2579 return Map::cast(prototype_or_initial_map());
2580}
2581
2582
2583void JSFunction::set_initial_map(Map* value) {
2584 set_prototype_or_initial_map(value);
2585}
2586
2587
2588bool JSFunction::has_initial_map() {
2589 return prototype_or_initial_map()->IsMap();
2590}
2591
2592
2593bool JSFunction::has_instance_prototype() {
2594 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2595}
2596
2597
2598bool JSFunction::has_prototype() {
2599 return map()->has_non_instance_prototype() || has_instance_prototype();
2600}
2601
2602
2603Object* JSFunction::instance_prototype() {
2604 ASSERT(has_instance_prototype());
2605 if (has_initial_map()) return initial_map()->prototype();
2606 // When there is no initial map and the prototype is a JSObject, the
2607 // initial map field is used for the prototype field.
2608 return prototype_or_initial_map();
2609}
2610
2611
2612Object* JSFunction::prototype() {
2613 ASSERT(has_prototype());
2614 // If the function's prototype property has been set to a non-JSObject
2615 // value, that value is stored in the constructor field of the map.
2616 if (map()->has_non_instance_prototype()) return map()->constructor();
2617 return instance_prototype();
2618}
2619
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002620bool JSFunction::should_have_prototype() {
2621 return map()->function_with_prototype();
2622}
2623
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624
2625bool JSFunction::is_compiled() {
2626 return shared()->is_compiled();
2627}
2628
2629
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002630int JSFunction::NumberOfLiterals() {
2631 return literals()->length();
2632}
2633
2634
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002635Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2636 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002637 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002638}
2639
2640
2641void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2642 Object* value) {
2643 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002644 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2645 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2646}
2647
2648
2649Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2650 ASSERT(0 <= id && id < kJSBuiltinsCount);
2651 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2652}
2653
2654
2655void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2656 Code* value) {
2657 ASSERT(0 <= id && id < kJSBuiltinsCount);
2658 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2659 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002660}
2661
2662
2663Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002664 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665}
2666
2667
2668void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002669 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002670}
2671
2672
2673void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2674 visitor->VisitExternalReference(
2675 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2676}
2677
2678
2679ACCESSORS(JSValue, value, Object, kValueOffset)
2680
2681
2682JSValue* JSValue::cast(Object* obj) {
2683 ASSERT(obj->IsJSValue());
2684 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2685 return reinterpret_cast<JSValue*>(obj);
2686}
2687
2688
2689INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2690INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2691INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2692
2693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002694byte* Code::instruction_start() {
2695 return FIELD_ADDR(this, kHeaderSize);
2696}
2697
2698
2699int Code::body_size() {
2700 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2701}
2702
2703
2704byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002705 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002706}
2707
2708
2709byte* Code::entry() {
2710 return instruction_start();
2711}
2712
2713
2714bool Code::contains(byte* pc) {
2715 return (instruction_start() <= pc) &&
2716 (pc < instruction_start() + instruction_size());
2717}
2718
2719
2720byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002721 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002722}
2723
2724
2725ACCESSORS(JSArray, length, Object, kLengthOffset)
2726
2727
ager@chromium.org236ad962008-09-25 09:45:57 +00002728ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002729
2730
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002731JSRegExp::Type JSRegExp::TypeTag() {
2732 Object* data = this->data();
2733 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2734 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2735 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002736}
2737
2738
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002739int JSRegExp::CaptureCount() {
2740 switch (TypeTag()) {
2741 case ATOM:
2742 return 0;
2743 case IRREGEXP:
2744 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2745 default:
2746 UNREACHABLE();
2747 return -1;
2748 }
2749}
2750
2751
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002752JSRegExp::Flags JSRegExp::GetFlags() {
2753 ASSERT(this->data()->IsFixedArray());
2754 Object* data = this->data();
2755 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2756 return Flags(smi->value());
2757}
2758
2759
2760String* JSRegExp::Pattern() {
2761 ASSERT(this->data()->IsFixedArray());
2762 Object* data = this->data();
2763 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2764 return pattern;
2765}
2766
2767
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002768Object* JSRegExp::DataAt(int index) {
2769 ASSERT(TypeTag() != NOT_COMPILED);
2770 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002771}
2772
2773
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002774void JSRegExp::SetDataAt(int index, Object* value) {
2775 ASSERT(TypeTag() != NOT_COMPILED);
2776 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2777 FixedArray::cast(data())->set(index, value);
2778}
2779
2780
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002781JSObject::ElementsKind JSObject::GetElementsKind() {
2782 Array* array = elements();
2783 if (array->IsFixedArray()) {
2784 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2785 if (array->map() == Heap::fixed_array_map()) {
2786 return FAST_ELEMENTS;
2787 }
2788 ASSERT(array->IsDictionary());
2789 return DICTIONARY_ELEMENTS;
2790 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002791 if (array->IsExternalArray()) {
2792 switch (array->map()->instance_type()) {
2793 case EXTERNAL_BYTE_ARRAY_TYPE:
2794 return EXTERNAL_BYTE_ELEMENTS;
2795 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2796 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2797 case EXTERNAL_SHORT_ARRAY_TYPE:
2798 return EXTERNAL_SHORT_ELEMENTS;
2799 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2800 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2801 case EXTERNAL_INT_ARRAY_TYPE:
2802 return EXTERNAL_INT_ELEMENTS;
2803 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2804 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2805 default:
2806 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2807 return EXTERNAL_FLOAT_ELEMENTS;
2808 }
2809 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002810 ASSERT(array->IsPixelArray());
2811 return PIXEL_ELEMENTS;
2812}
2813
2814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002816 return GetElementsKind() == FAST_ELEMENTS;
2817}
2818
2819
2820bool JSObject::HasDictionaryElements() {
2821 return GetElementsKind() == DICTIONARY_ELEMENTS;
2822}
2823
2824
2825bool JSObject::HasPixelElements() {
2826 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827}
2828
2829
ager@chromium.org3811b432009-10-28 14:53:37 +00002830bool JSObject::HasExternalArrayElements() {
2831 return (HasExternalByteElements() ||
2832 HasExternalUnsignedByteElements() ||
2833 HasExternalShortElements() ||
2834 HasExternalUnsignedShortElements() ||
2835 HasExternalIntElements() ||
2836 HasExternalUnsignedIntElements() ||
2837 HasExternalFloatElements());
2838}
2839
2840
2841bool JSObject::HasExternalByteElements() {
2842 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2843}
2844
2845
2846bool JSObject::HasExternalUnsignedByteElements() {
2847 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2848}
2849
2850
2851bool JSObject::HasExternalShortElements() {
2852 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2853}
2854
2855
2856bool JSObject::HasExternalUnsignedShortElements() {
2857 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2858}
2859
2860
2861bool JSObject::HasExternalIntElements() {
2862 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2863}
2864
2865
2866bool JSObject::HasExternalUnsignedIntElements() {
2867 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2868}
2869
2870
2871bool JSObject::HasExternalFloatElements() {
2872 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2873}
2874
2875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876bool JSObject::HasNamedInterceptor() {
2877 return map()->has_named_interceptor();
2878}
2879
2880
2881bool JSObject::HasIndexedInterceptor() {
2882 return map()->has_indexed_interceptor();
2883}
2884
2885
ager@chromium.org5c838252010-02-19 08:53:10 +00002886bool JSObject::AllowsSetElementsLength() {
2887 bool result = elements()->IsFixedArray();
2888 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2889 return result;
2890}
2891
2892
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002893StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002894 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002895 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002896}
2897
2898
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002899NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002900 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002901 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902}
2903
2904
2905bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002906 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002907}
2908
2909
2910uint32_t String::Hash() {
2911 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002912 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002913 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002914 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915 return ComputeAndSetHash();
2916}
2917
2918
ager@chromium.org7c537e22008-10-16 08:43:32 +00002919StringHasher::StringHasher(int length)
2920 : length_(length),
2921 raw_running_hash_(0),
2922 array_index_(0),
2923 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2924 is_first_char_(true),
2925 is_valid_(true) { }
2926
2927
2928bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002929 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002930}
2931
2932
2933void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002934 // Use the Jenkins one-at-a-time hash function to update the hash
2935 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002936 raw_running_hash_ += c;
2937 raw_running_hash_ += (raw_running_hash_ << 10);
2938 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002939 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002940 if (is_array_index_) {
2941 if (c < '0' || c > '9') {
2942 is_array_index_ = false;
2943 } else {
2944 int d = c - '0';
2945 if (is_first_char_) {
2946 is_first_char_ = false;
2947 if (c == '0' && length_ > 1) {
2948 is_array_index_ = false;
2949 return;
2950 }
2951 }
2952 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2953 is_array_index_ = false;
2954 } else {
2955 array_index_ = array_index_ * 10 + d;
2956 }
2957 }
2958 }
2959}
2960
2961
2962void StringHasher::AddCharacterNoIndex(uc32 c) {
2963 ASSERT(!is_array_index());
2964 raw_running_hash_ += c;
2965 raw_running_hash_ += (raw_running_hash_ << 10);
2966 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2967}
2968
2969
2970uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002971 // Get the calculated raw hash value and do some more bit ops to distribute
2972 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002973 uint32_t result = raw_running_hash_;
2974 result += (result << 3);
2975 result ^= (result >> 11);
2976 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002977 if (result == 0) {
2978 result = 27;
2979 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002980 return result;
2981}
2982
2983
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002985 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002986 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002987 return SlowAsArrayIndex(index);
2988}
2989
2990
2991Object* JSObject::GetPrototype() {
2992 return JSObject::cast(this)->map()->prototype();
2993}
2994
2995
2996PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2997 return GetPropertyAttributeWithReceiver(this, key);
2998}
2999
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003000// TODO(504): this may be useful in other places too where JSGlobalProxy
3001// is used.
3002Object* JSObject::BypassGlobalProxy() {
3003 if (IsJSGlobalProxy()) {
3004 Object* proto = GetPrototype();
3005 if (proto->IsNull()) return Heap::undefined_value();
3006 ASSERT(proto->IsJSGlobalObject());
3007 return proto;
3008 }
3009 return this;
3010}
3011
3012
3013bool JSObject::HasHiddenPropertiesObject() {
3014 ASSERT(!IsJSGlobalProxy());
3015 return GetPropertyAttributePostInterceptor(this,
3016 Heap::hidden_symbol(),
3017 false) != ABSENT;
3018}
3019
3020
3021Object* JSObject::GetHiddenPropertiesObject() {
3022 ASSERT(!IsJSGlobalProxy());
3023 PropertyAttributes attributes;
3024 return GetLocalPropertyPostInterceptor(this,
3025 Heap::hidden_symbol(),
3026 &attributes);
3027}
3028
3029
3030Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3031 ASSERT(!IsJSGlobalProxy());
3032 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3033 hidden_obj,
3034 DONT_ENUM);
3035}
3036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003037
3038bool JSObject::HasElement(uint32_t index) {
3039 return HasElementWithReceiver(this, index);
3040}
3041
3042
3043bool AccessorInfo::all_can_read() {
3044 return BooleanBit::get(flag(), kAllCanReadBit);
3045}
3046
3047
3048void AccessorInfo::set_all_can_read(bool value) {
3049 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3050}
3051
3052
3053bool AccessorInfo::all_can_write() {
3054 return BooleanBit::get(flag(), kAllCanWriteBit);
3055}
3056
3057
3058void AccessorInfo::set_all_can_write(bool value) {
3059 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3060}
3061
3062
ager@chromium.org870a0b62008-11-04 11:43:05 +00003063bool AccessorInfo::prohibits_overwriting() {
3064 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3065}
3066
3067
3068void AccessorInfo::set_prohibits_overwriting(bool value) {
3069 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3070}
3071
3072
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003073PropertyAttributes AccessorInfo::property_attributes() {
3074 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3075}
3076
3077
3078void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3079 ASSERT(AttributesField::is_valid(attributes));
3080 int rest_value = flag()->value() & ~AttributesField::mask();
3081 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3082}
3083
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003084template<typename Shape, typename Key>
3085void Dictionary<Shape, Key>::SetEntry(int entry,
3086 Object* key,
3087 Object* value,
3088 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003089 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003090 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003091 AssertNoAllocation no_gc;
3092 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003093 FixedArray::set(index, key, mode);
3094 FixedArray::set(index+1, value, mode);
3095 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096}
3097
3098
3099void Map::ClearCodeCache() {
3100 // No write barrier is needed since empty_fixed_array is not in new space.
3101 // Please note this function is used during marking:
3102 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003103 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3104 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003105}
3106
3107
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003108void JSArray::EnsureSize(int required_size) {
3109 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003110 Array* elts = elements();
3111 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3112 if (elts->length() < required_size) {
3113 // Doubling in size would be overkill, but leave some slack to avoid
3114 // constantly growing.
3115 Expand(required_size + (required_size >> 3));
3116 // It's a performance benefit to keep a frequently used array in new-space.
3117 } else if (!Heap::new_space()->Contains(elts) &&
3118 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3119 // Expand will allocate a new backing store in new space even if the size
3120 // we asked for isn't larger than what we had before.
3121 Expand(required_size);
3122 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003123}
3124
3125
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003126void JSArray::set_length(Smi* length) {
3127 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3128}
3129
3130
ager@chromium.org7c537e22008-10-16 08:43:32 +00003131void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003132 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003133 set_elements(storage);
3134}
3135
3136
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003137Object* FixedArray::Copy() {
3138 if (length() == 0) return this;
3139 return Heap::CopyFixedArray(this);
3140}
3141
3142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143#undef CAST_ACCESSOR
3144#undef INT_ACCESSORS
3145#undef SMI_ACCESSORS
3146#undef ACCESSORS
3147#undef FIELD_ADDR
3148#undef READ_FIELD
3149#undef WRITE_FIELD
3150#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003151#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003152#undef READ_MEMADDR_FIELD
3153#undef WRITE_MEMADDR_FIELD
3154#undef READ_DOUBLE_FIELD
3155#undef WRITE_DOUBLE_FIELD
3156#undef READ_INT_FIELD
3157#undef WRITE_INT_FIELD
3158#undef READ_SHORT_FIELD
3159#undef WRITE_SHORT_FIELD
3160#undef READ_BYTE_FIELD
3161#undef WRITE_BYTE_FIELD
3162
3163
3164} } // namespace v8::internal
3165
3166#endif // V8_OBJECTS_INL_H_