blob: ae7d2c2a97201de87ca7bc89e547462d1f8cf4e3 [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() {
2533 return function_data()->IsProxy();
2534}
2535
2536
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002537bool JSFunction::IsBuiltin() {
2538 return context()->global()->IsJSBuiltinsObject();
2539}
2540
2541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002542Code* JSFunction::code() {
2543 return shared()->code();
2544}
2545
2546
2547void JSFunction::set_code(Code* value) {
2548 shared()->set_code(value);
2549}
2550
2551
2552Context* JSFunction::context() {
2553 return Context::cast(READ_FIELD(this, kContextOffset));
2554}
2555
2556
2557Object* JSFunction::unchecked_context() {
2558 return READ_FIELD(this, kContextOffset);
2559}
2560
2561
2562void JSFunction::set_context(Object* value) {
2563 ASSERT(value == Heap::undefined_value() || value->IsContext());
2564 WRITE_FIELD(this, kContextOffset, value);
2565 WRITE_BARRIER(this, kContextOffset);
2566}
2567
2568ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2569 kPrototypeOrInitialMapOffset)
2570
2571
2572Map* JSFunction::initial_map() {
2573 return Map::cast(prototype_or_initial_map());
2574}
2575
2576
2577void JSFunction::set_initial_map(Map* value) {
2578 set_prototype_or_initial_map(value);
2579}
2580
2581
2582bool JSFunction::has_initial_map() {
2583 return prototype_or_initial_map()->IsMap();
2584}
2585
2586
2587bool JSFunction::has_instance_prototype() {
2588 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2589}
2590
2591
2592bool JSFunction::has_prototype() {
2593 return map()->has_non_instance_prototype() || has_instance_prototype();
2594}
2595
2596
2597Object* JSFunction::instance_prototype() {
2598 ASSERT(has_instance_prototype());
2599 if (has_initial_map()) return initial_map()->prototype();
2600 // When there is no initial map and the prototype is a JSObject, the
2601 // initial map field is used for the prototype field.
2602 return prototype_or_initial_map();
2603}
2604
2605
2606Object* JSFunction::prototype() {
2607 ASSERT(has_prototype());
2608 // If the function's prototype property has been set to a non-JSObject
2609 // value, that value is stored in the constructor field of the map.
2610 if (map()->has_non_instance_prototype()) return map()->constructor();
2611 return instance_prototype();
2612}
2613
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002614bool JSFunction::should_have_prototype() {
2615 return map()->function_with_prototype();
2616}
2617
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002618
2619bool JSFunction::is_compiled() {
2620 return shared()->is_compiled();
2621}
2622
2623
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002624int JSFunction::NumberOfLiterals() {
2625 return literals()->length();
2626}
2627
2628
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002629Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2630 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002631 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632}
2633
2634
2635void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2636 Object* value) {
2637 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002638 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2639 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2640}
2641
2642
2643Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2644 ASSERT(0 <= id && id < kJSBuiltinsCount);
2645 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2646}
2647
2648
2649void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2650 Code* value) {
2651 ASSERT(0 <= id && id < kJSBuiltinsCount);
2652 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2653 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002654}
2655
2656
2657Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002658 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659}
2660
2661
2662void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002663 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664}
2665
2666
2667void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2668 visitor->VisitExternalReference(
2669 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2670}
2671
2672
2673ACCESSORS(JSValue, value, Object, kValueOffset)
2674
2675
2676JSValue* JSValue::cast(Object* obj) {
2677 ASSERT(obj->IsJSValue());
2678 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2679 return reinterpret_cast<JSValue*>(obj);
2680}
2681
2682
2683INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2684INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2685INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2686
2687
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002688byte* Code::instruction_start() {
2689 return FIELD_ADDR(this, kHeaderSize);
2690}
2691
2692
2693int Code::body_size() {
2694 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2695}
2696
2697
2698byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002699 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700}
2701
2702
2703byte* Code::entry() {
2704 return instruction_start();
2705}
2706
2707
2708bool Code::contains(byte* pc) {
2709 return (instruction_start() <= pc) &&
2710 (pc < instruction_start() + instruction_size());
2711}
2712
2713
2714byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002715 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002716}
2717
2718
2719ACCESSORS(JSArray, length, Object, kLengthOffset)
2720
2721
ager@chromium.org236ad962008-09-25 09:45:57 +00002722ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002723
2724
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002725JSRegExp::Type JSRegExp::TypeTag() {
2726 Object* data = this->data();
2727 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2728 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2729 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002730}
2731
2732
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002733int JSRegExp::CaptureCount() {
2734 switch (TypeTag()) {
2735 case ATOM:
2736 return 0;
2737 case IRREGEXP:
2738 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2739 default:
2740 UNREACHABLE();
2741 return -1;
2742 }
2743}
2744
2745
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002746JSRegExp::Flags JSRegExp::GetFlags() {
2747 ASSERT(this->data()->IsFixedArray());
2748 Object* data = this->data();
2749 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2750 return Flags(smi->value());
2751}
2752
2753
2754String* JSRegExp::Pattern() {
2755 ASSERT(this->data()->IsFixedArray());
2756 Object* data = this->data();
2757 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2758 return pattern;
2759}
2760
2761
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002762Object* JSRegExp::DataAt(int index) {
2763 ASSERT(TypeTag() != NOT_COMPILED);
2764 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002765}
2766
2767
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002768void JSRegExp::SetDataAt(int index, Object* value) {
2769 ASSERT(TypeTag() != NOT_COMPILED);
2770 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2771 FixedArray::cast(data())->set(index, value);
2772}
2773
2774
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002775JSObject::ElementsKind JSObject::GetElementsKind() {
2776 Array* array = elements();
2777 if (array->IsFixedArray()) {
2778 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2779 if (array->map() == Heap::fixed_array_map()) {
2780 return FAST_ELEMENTS;
2781 }
2782 ASSERT(array->IsDictionary());
2783 return DICTIONARY_ELEMENTS;
2784 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002785 if (array->IsExternalArray()) {
2786 switch (array->map()->instance_type()) {
2787 case EXTERNAL_BYTE_ARRAY_TYPE:
2788 return EXTERNAL_BYTE_ELEMENTS;
2789 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2790 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2791 case EXTERNAL_SHORT_ARRAY_TYPE:
2792 return EXTERNAL_SHORT_ELEMENTS;
2793 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2794 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2795 case EXTERNAL_INT_ARRAY_TYPE:
2796 return EXTERNAL_INT_ELEMENTS;
2797 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2798 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2799 default:
2800 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2801 return EXTERNAL_FLOAT_ELEMENTS;
2802 }
2803 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002804 ASSERT(array->IsPixelArray());
2805 return PIXEL_ELEMENTS;
2806}
2807
2808
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002810 return GetElementsKind() == FAST_ELEMENTS;
2811}
2812
2813
2814bool JSObject::HasDictionaryElements() {
2815 return GetElementsKind() == DICTIONARY_ELEMENTS;
2816}
2817
2818
2819bool JSObject::HasPixelElements() {
2820 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002821}
2822
2823
ager@chromium.org3811b432009-10-28 14:53:37 +00002824bool JSObject::HasExternalArrayElements() {
2825 return (HasExternalByteElements() ||
2826 HasExternalUnsignedByteElements() ||
2827 HasExternalShortElements() ||
2828 HasExternalUnsignedShortElements() ||
2829 HasExternalIntElements() ||
2830 HasExternalUnsignedIntElements() ||
2831 HasExternalFloatElements());
2832}
2833
2834
2835bool JSObject::HasExternalByteElements() {
2836 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2837}
2838
2839
2840bool JSObject::HasExternalUnsignedByteElements() {
2841 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2842}
2843
2844
2845bool JSObject::HasExternalShortElements() {
2846 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2847}
2848
2849
2850bool JSObject::HasExternalUnsignedShortElements() {
2851 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2852}
2853
2854
2855bool JSObject::HasExternalIntElements() {
2856 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2857}
2858
2859
2860bool JSObject::HasExternalUnsignedIntElements() {
2861 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2862}
2863
2864
2865bool JSObject::HasExternalFloatElements() {
2866 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2867}
2868
2869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002870bool JSObject::HasNamedInterceptor() {
2871 return map()->has_named_interceptor();
2872}
2873
2874
2875bool JSObject::HasIndexedInterceptor() {
2876 return map()->has_indexed_interceptor();
2877}
2878
2879
ager@chromium.org5c838252010-02-19 08:53:10 +00002880bool JSObject::AllowsSetElementsLength() {
2881 bool result = elements()->IsFixedArray();
2882 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2883 return result;
2884}
2885
2886
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002887StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002888 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002889 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002890}
2891
2892
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002893NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002894 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002895 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002896}
2897
2898
2899bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002900 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002901}
2902
2903
2904uint32_t String::Hash() {
2905 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002906 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002907 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002908 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909 return ComputeAndSetHash();
2910}
2911
2912
ager@chromium.org7c537e22008-10-16 08:43:32 +00002913StringHasher::StringHasher(int length)
2914 : length_(length),
2915 raw_running_hash_(0),
2916 array_index_(0),
2917 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2918 is_first_char_(true),
2919 is_valid_(true) { }
2920
2921
2922bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002923 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002924}
2925
2926
2927void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002928 // Use the Jenkins one-at-a-time hash function to update the hash
2929 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002930 raw_running_hash_ += c;
2931 raw_running_hash_ += (raw_running_hash_ << 10);
2932 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002933 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002934 if (is_array_index_) {
2935 if (c < '0' || c > '9') {
2936 is_array_index_ = false;
2937 } else {
2938 int d = c - '0';
2939 if (is_first_char_) {
2940 is_first_char_ = false;
2941 if (c == '0' && length_ > 1) {
2942 is_array_index_ = false;
2943 return;
2944 }
2945 }
2946 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2947 is_array_index_ = false;
2948 } else {
2949 array_index_ = array_index_ * 10 + d;
2950 }
2951 }
2952 }
2953}
2954
2955
2956void StringHasher::AddCharacterNoIndex(uc32 c) {
2957 ASSERT(!is_array_index());
2958 raw_running_hash_ += c;
2959 raw_running_hash_ += (raw_running_hash_ << 10);
2960 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2961}
2962
2963
2964uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002965 // Get the calculated raw hash value and do some more bit ops to distribute
2966 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002967 uint32_t result = raw_running_hash_;
2968 result += (result << 3);
2969 result ^= (result >> 11);
2970 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002971 if (result == 0) {
2972 result = 27;
2973 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002974 return result;
2975}
2976
2977
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002979 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002980 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002981 return SlowAsArrayIndex(index);
2982}
2983
2984
2985Object* JSObject::GetPrototype() {
2986 return JSObject::cast(this)->map()->prototype();
2987}
2988
2989
2990PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2991 return GetPropertyAttributeWithReceiver(this, key);
2992}
2993
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002994// TODO(504): this may be useful in other places too where JSGlobalProxy
2995// is used.
2996Object* JSObject::BypassGlobalProxy() {
2997 if (IsJSGlobalProxy()) {
2998 Object* proto = GetPrototype();
2999 if (proto->IsNull()) return Heap::undefined_value();
3000 ASSERT(proto->IsJSGlobalObject());
3001 return proto;
3002 }
3003 return this;
3004}
3005
3006
3007bool JSObject::HasHiddenPropertiesObject() {
3008 ASSERT(!IsJSGlobalProxy());
3009 return GetPropertyAttributePostInterceptor(this,
3010 Heap::hidden_symbol(),
3011 false) != ABSENT;
3012}
3013
3014
3015Object* JSObject::GetHiddenPropertiesObject() {
3016 ASSERT(!IsJSGlobalProxy());
3017 PropertyAttributes attributes;
3018 return GetLocalPropertyPostInterceptor(this,
3019 Heap::hidden_symbol(),
3020 &attributes);
3021}
3022
3023
3024Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3025 ASSERT(!IsJSGlobalProxy());
3026 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3027 hidden_obj,
3028 DONT_ENUM);
3029}
3030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003031
3032bool JSObject::HasElement(uint32_t index) {
3033 return HasElementWithReceiver(this, index);
3034}
3035
3036
3037bool AccessorInfo::all_can_read() {
3038 return BooleanBit::get(flag(), kAllCanReadBit);
3039}
3040
3041
3042void AccessorInfo::set_all_can_read(bool value) {
3043 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3044}
3045
3046
3047bool AccessorInfo::all_can_write() {
3048 return BooleanBit::get(flag(), kAllCanWriteBit);
3049}
3050
3051
3052void AccessorInfo::set_all_can_write(bool value) {
3053 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3054}
3055
3056
ager@chromium.org870a0b62008-11-04 11:43:05 +00003057bool AccessorInfo::prohibits_overwriting() {
3058 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3059}
3060
3061
3062void AccessorInfo::set_prohibits_overwriting(bool value) {
3063 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3064}
3065
3066
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067PropertyAttributes AccessorInfo::property_attributes() {
3068 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3069}
3070
3071
3072void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3073 ASSERT(AttributesField::is_valid(attributes));
3074 int rest_value = flag()->value() & ~AttributesField::mask();
3075 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3076}
3077
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003078template<typename Shape, typename Key>
3079void Dictionary<Shape, Key>::SetEntry(int entry,
3080 Object* key,
3081 Object* value,
3082 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003083 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003084 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003085 AssertNoAllocation no_gc;
3086 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003087 FixedArray::set(index, key, mode);
3088 FixedArray::set(index+1, value, mode);
3089 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003090}
3091
3092
3093void Map::ClearCodeCache() {
3094 // No write barrier is needed since empty_fixed_array is not in new space.
3095 // Please note this function is used during marking:
3096 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003097 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3098 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003099}
3100
3101
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003102void JSArray::EnsureSize(int required_size) {
3103 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003104 Array* elts = elements();
3105 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3106 if (elts->length() < required_size) {
3107 // Doubling in size would be overkill, but leave some slack to avoid
3108 // constantly growing.
3109 Expand(required_size + (required_size >> 3));
3110 // It's a performance benefit to keep a frequently used array in new-space.
3111 } else if (!Heap::new_space()->Contains(elts) &&
3112 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3113 // Expand will allocate a new backing store in new space even if the size
3114 // we asked for isn't larger than what we had before.
3115 Expand(required_size);
3116 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003117}
3118
3119
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003120void JSArray::set_length(Smi* length) {
3121 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3122}
3123
3124
ager@chromium.org7c537e22008-10-16 08:43:32 +00003125void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003126 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003127 set_elements(storage);
3128}
3129
3130
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003131Object* FixedArray::Copy() {
3132 if (length() == 0) return this;
3133 return Heap::CopyFixedArray(this);
3134}
3135
3136
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003137#undef CAST_ACCESSOR
3138#undef INT_ACCESSORS
3139#undef SMI_ACCESSORS
3140#undef ACCESSORS
3141#undef FIELD_ADDR
3142#undef READ_FIELD
3143#undef WRITE_FIELD
3144#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003145#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003146#undef READ_MEMADDR_FIELD
3147#undef WRITE_MEMADDR_FIELD
3148#undef READ_DOUBLE_FIELD
3149#undef WRITE_DOUBLE_FIELD
3150#undef READ_INT_FIELD
3151#undef WRITE_INT_FIELD
3152#undef READ_SHORT_FIELD
3153#undef WRITE_SHORT_FIELD
3154#undef READ_BYTE_FIELD
3155#undef WRITE_BYTE_FIELD
3156
3157
3158} } // namespace v8::internal
3159
3160#endif // V8_OBJECTS_INL_H_