blob: c10c930d31958cce7cc7953f63da4119636f69c1 [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)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000762 Page::FromAddress(object->address())-> \
763 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000764 }
765
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000766#define READ_DOUBLE_FIELD(p, offset) \
767 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
768
769#define WRITE_DOUBLE_FIELD(p, offset, value) \
770 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
771
772#define READ_INT_FIELD(p, offset) \
773 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
774
775#define WRITE_INT_FIELD(p, offset, value) \
776 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
777
ager@chromium.org3e875802009-06-29 08:26:34 +0000778#define READ_INTPTR_FIELD(p, offset) \
779 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
780
781#define WRITE_INTPTR_FIELD(p, offset, value) \
782 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
783
ager@chromium.org7c537e22008-10-16 08:43:32 +0000784#define READ_UINT32_FIELD(p, offset) \
785 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
786
787#define WRITE_UINT32_FIELD(p, offset, value) \
788 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790#define READ_SHORT_FIELD(p, offset) \
791 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
792
793#define WRITE_SHORT_FIELD(p, offset, value) \
794 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
795
796#define READ_BYTE_FIELD(p, offset) \
797 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
798
799#define WRITE_BYTE_FIELD(p, offset, value) \
800 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
801
802
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000803Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
804 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000805}
806
807
808int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000809 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810}
811
812
813Smi* Smi::FromInt(int value) {
814 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000815 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000816 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000817 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000818 return reinterpret_cast<Smi*>(tagged_value);
819}
820
821
822Smi* Smi::FromIntptr(intptr_t value) {
823 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000824 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
825 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826}
827
828
829Failure::Type Failure::type() const {
830 return static_cast<Type>(value() & kFailureTypeTagMask);
831}
832
833
834bool Failure::IsInternalError() const {
835 return type() == INTERNAL_ERROR;
836}
837
838
839bool Failure::IsOutOfMemoryException() const {
840 return type() == OUT_OF_MEMORY_EXCEPTION;
841}
842
843
844int Failure::requested() const {
845 const int kShiftBits =
846 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
847 STATIC_ASSERT(kShiftBits >= 0);
848 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000849 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850}
851
852
853AllocationSpace Failure::allocation_space() const {
854 ASSERT_EQ(RETRY_AFTER_GC, type());
855 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
856 & kSpaceTagMask);
857}
858
859
860Failure* Failure::InternalError() {
861 return Construct(INTERNAL_ERROR);
862}
863
864
865Failure* Failure::Exception() {
866 return Construct(EXCEPTION);
867}
868
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870Failure* Failure::OutOfMemoryException() {
871 return Construct(OUT_OF_MEMORY_EXCEPTION);
872}
873
874
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000875intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000876 return static_cast<intptr_t>(
877 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000878}
879
880
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000881Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000882 // Assert that the space encoding fits in the three bytes allotted for it.
883 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000884 uintptr_t requested =
885 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
886 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000887 if (((requested << tag_bits) >> tag_bits) != requested) {
888 // No room for entire requested size in the bits. Round down to
889 // maximally representable size.
890 requested = static_cast<intptr_t>(
891 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
892 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000893 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000894 return Construct(RETRY_AFTER_GC, value);
895}
896
897
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000899 uintptr_t info =
900 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000901 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000902 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903}
904
905
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000906bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907#ifdef DEBUG
908 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
909#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000910
911#ifdef V8_TARGET_ARCH_X64
912 // To be representable as a long smi, the value must be a 32-bit integer.
913 bool result = (value == static_cast<int32_t>(value));
914#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000915 // To be representable as an tagged small integer, the two
916 // most-significant bits of 'value' must be either 00 or 11 due to
917 // sign-extension. To check this we add 01 to the two
918 // most-significant bits, and check if the most-significant bit is 0
919 //
920 // CAUTION: The original code below:
921 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
922 // may lead to incorrect results according to the C language spec, and
923 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
924 // compiler may produce undefined results in case of signed integer
925 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000926 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000927#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000928 ASSERT(result == in_range);
929 return result;
930}
931
932
kasper.lund7276f142008-07-30 08:49:36 +0000933MapWord MapWord::FromMap(Map* map) {
934 return MapWord(reinterpret_cast<uintptr_t>(map));
935}
936
937
938Map* MapWord::ToMap() {
939 return reinterpret_cast<Map*>(value_);
940}
941
942
943bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000944 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000945}
946
947
948MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000949 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
950 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000951}
952
953
954HeapObject* MapWord::ToForwardingAddress() {
955 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000956 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000957}
958
959
960bool MapWord::IsMarked() {
961 return (value_ & kMarkingMask) == 0;
962}
963
964
965void MapWord::SetMark() {
966 value_ &= ~kMarkingMask;
967}
968
969
970void MapWord::ClearMark() {
971 value_ |= kMarkingMask;
972}
973
974
975bool MapWord::IsOverflowed() {
976 return (value_ & kOverflowMask) != 0;
977}
978
979
980void MapWord::SetOverflow() {
981 value_ |= kOverflowMask;
982}
983
984
985void MapWord::ClearOverflow() {
986 value_ &= ~kOverflowMask;
987}
988
989
990MapWord MapWord::EncodeAddress(Address map_address, int offset) {
991 // Offset is the distance in live bytes from the first live object in the
992 // same page. The offset between two objects in the same page should not
993 // exceed the object area size of a page.
994 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
995
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000996 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000997 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
998
999 Page* map_page = Page::FromAddress(map_address);
1000 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1001
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001002 uintptr_t map_page_offset =
1003 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001004
1005 uintptr_t encoding =
1006 (compact_offset << kForwardingOffsetShift) |
1007 (map_page_offset << kMapPageOffsetShift) |
1008 (map_page->mc_page_index << kMapPageIndexShift);
1009 return MapWord(encoding);
1010}
1011
1012
1013Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001014 int map_page_index =
1015 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001016 ASSERT_MAP_PAGE_INDEX(map_page_index);
1017
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001019 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1020 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001021
1022 return (map_space->PageAddress(map_page_index) + map_page_offset);
1023}
1024
1025
1026int MapWord::DecodeOffset() {
1027 // The offset field is represented in the kForwardingOffsetBits
1028 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001029 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1030 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1031 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001032}
1033
1034
1035MapWord MapWord::FromEncodedAddress(Address address) {
1036 return MapWord(reinterpret_cast<uintptr_t>(address));
1037}
1038
1039
1040Address MapWord::ToEncodedAddress() {
1041 return reinterpret_cast<Address>(value_);
1042}
1043
1044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045#ifdef DEBUG
1046void HeapObject::VerifyObjectField(int offset) {
1047 VerifyPointer(READ_FIELD(this, offset));
1048}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001049
1050void HeapObject::VerifySmiField(int offset) {
1051 ASSERT(READ_FIELD(this, offset)->IsSmi());
1052}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053#endif
1054
1055
1056Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001057 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058}
1059
1060
1061void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001062 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001063}
1064
1065
kasper.lund7276f142008-07-30 08:49:36 +00001066MapWord HeapObject::map_word() {
1067 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1068}
1069
1070
1071void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001072 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001073 // here.
1074 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1075}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001076
1077
1078HeapObject* HeapObject::FromAddress(Address address) {
1079 ASSERT_TAG_ALIGNED(address);
1080 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1081}
1082
1083
1084Address HeapObject::address() {
1085 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1086}
1087
1088
1089int HeapObject::Size() {
1090 return SizeFromMap(map());
1091}
1092
1093
1094void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1095 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1096 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1097}
1098
1099
1100void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1101 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1102}
1103
1104
kasper.lund7276f142008-07-30 08:49:36 +00001105bool HeapObject::IsMarked() {
1106 return map_word().IsMarked();
1107}
1108
1109
1110void HeapObject::SetMark() {
1111 ASSERT(!IsMarked());
1112 MapWord first_word = map_word();
1113 first_word.SetMark();
1114 set_map_word(first_word);
1115}
1116
1117
1118void HeapObject::ClearMark() {
1119 ASSERT(IsMarked());
1120 MapWord first_word = map_word();
1121 first_word.ClearMark();
1122 set_map_word(first_word);
1123}
1124
1125
1126bool HeapObject::IsOverflowed() {
1127 return map_word().IsOverflowed();
1128}
1129
1130
1131void HeapObject::SetOverflow() {
1132 MapWord first_word = map_word();
1133 first_word.SetOverflow();
1134 set_map_word(first_word);
1135}
1136
1137
1138void HeapObject::ClearOverflow() {
1139 ASSERT(IsOverflowed());
1140 MapWord first_word = map_word();
1141 first_word.ClearOverflow();
1142 set_map_word(first_word);
1143}
1144
1145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001146double HeapNumber::value() {
1147 return READ_DOUBLE_FIELD(this, kValueOffset);
1148}
1149
1150
1151void HeapNumber::set_value(double value) {
1152 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1153}
1154
1155
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001156int HeapNumber::get_exponent() {
1157 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1158 kExponentShift) - kExponentBias;
1159}
1160
1161
1162int HeapNumber::get_sign() {
1163 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1164}
1165
1166
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001167ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001168
1169
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001170HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001171 Object* array = READ_FIELD(this, kElementsOffset);
1172 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001173 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1174 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001175 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001176}
1177
1178
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001179void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001180 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001181 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1182 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001183 WRITE_FIELD(this, kElementsOffset, value);
1184 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1185}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186
1187
1188void JSObject::initialize_properties() {
1189 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1190 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1191}
1192
1193
1194void JSObject::initialize_elements() {
1195 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1196 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1197}
1198
1199
1200ACCESSORS(Oddball, to_string, String, kToStringOffset)
1201ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1202
1203
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001204Object* JSGlobalPropertyCell::value() {
1205 return READ_FIELD(this, kValueOffset);
1206}
1207
1208
1209void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1210 // The write barrier is not used for global property cells.
1211 ASSERT(!val->IsJSGlobalPropertyCell());
1212 WRITE_FIELD(this, kValueOffset, val);
1213}
1214
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001216int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001217 InstanceType type = map()->instance_type();
1218 // Check for the most common kind of JavaScript object before
1219 // falling into the generic switch. This speeds up the internal
1220 // field operations considerably on average.
1221 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1222 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001223 case JS_GLOBAL_PROXY_TYPE:
1224 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001225 case JS_GLOBAL_OBJECT_TYPE:
1226 return JSGlobalObject::kSize;
1227 case JS_BUILTINS_OBJECT_TYPE:
1228 return JSBuiltinsObject::kSize;
1229 case JS_FUNCTION_TYPE:
1230 return JSFunction::kSize;
1231 case JS_VALUE_TYPE:
1232 return JSValue::kSize;
1233 case JS_ARRAY_TYPE:
1234 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001235 case JS_REGEXP_TYPE:
1236 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001237 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001238 return JSObject::kHeaderSize;
1239 default:
1240 UNREACHABLE();
1241 return 0;
1242 }
1243}
1244
1245
1246int JSObject::GetInternalFieldCount() {
1247 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001248 // Make sure to adjust for the number of in-object properties. These
1249 // properties do contribute to the size, but are not internal fields.
1250 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1251 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252}
1253
1254
1255Object* JSObject::GetInternalField(int index) {
1256 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001257 // Internal objects do follow immediately after the header, whereas in-object
1258 // properties are at the end of the object. Therefore there is no need
1259 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001260 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1261}
1262
1263
1264void JSObject::SetInternalField(int index, Object* value) {
1265 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001266 // Internal objects do follow immediately after the header, whereas in-object
1267 // properties are at the end of the object. Therefore there is no need
1268 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269 int offset = GetHeaderSize() + (kPointerSize * index);
1270 WRITE_FIELD(this, offset, value);
1271 WRITE_BARRIER(this, offset);
1272}
1273
1274
ager@chromium.org7c537e22008-10-16 08:43:32 +00001275// Access fast-case object properties at index. The use of these routines
1276// is needed to correctly distinguish between properties stored in-object and
1277// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001278Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001279 // Adjust for the number of properties stored in the object.
1280 index -= map()->inobject_properties();
1281 if (index < 0) {
1282 int offset = map()->instance_size() + (index * kPointerSize);
1283 return READ_FIELD(this, offset);
1284 } else {
1285 ASSERT(index < properties()->length());
1286 return properties()->get(index);
1287 }
1288}
1289
1290
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001291Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001292 // Adjust for the number of properties stored in the object.
1293 index -= map()->inobject_properties();
1294 if (index < 0) {
1295 int offset = map()->instance_size() + (index * kPointerSize);
1296 WRITE_FIELD(this, offset, value);
1297 WRITE_BARRIER(this, offset);
1298 } else {
1299 ASSERT(index < properties()->length());
1300 properties()->set(index, value);
1301 }
1302 return value;
1303}
1304
1305
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001306Object* JSObject::InObjectPropertyAt(int index) {
1307 // Adjust for the number of properties stored in the object.
1308 index -= map()->inobject_properties();
1309 ASSERT(index < 0);
1310 int offset = map()->instance_size() + (index * kPointerSize);
1311 return READ_FIELD(this, offset);
1312}
1313
1314
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001315Object* JSObject::InObjectPropertyAtPut(int index,
1316 Object* value,
1317 WriteBarrierMode mode) {
1318 // Adjust for the number of properties stored in the object.
1319 index -= map()->inobject_properties();
1320 ASSERT(index < 0);
1321 int offset = map()->instance_size() + (index * kPointerSize);
1322 WRITE_FIELD(this, offset, value);
1323 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1324 return value;
1325}
1326
1327
1328
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001329void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001330 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001332 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001333 }
1334}
1335
1336
1337void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001338 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001339 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001340 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001341 }
1342}
1343
1344
1345bool JSObject::HasFastProperties() {
1346 return !properties()->IsDictionary();
1347}
1348
1349
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001350bool Object::ToArrayIndex(uint32_t* index) {
1351 if (IsSmi()) {
1352 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001353 if (value < 0) return false;
1354 *index = value;
1355 return true;
1356 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001357 if (IsHeapNumber()) {
1358 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359 uint32_t uint_value = static_cast<uint32_t>(value);
1360 if (value == static_cast<double>(uint_value)) {
1361 *index = uint_value;
1362 return true;
1363 }
1364 }
1365 return false;
1366}
1367
1368
1369bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1370 if (!this->IsJSValue()) return false;
1371
1372 JSValue* js_value = JSValue::cast(this);
1373 if (!js_value->value()->IsString()) return false;
1374
1375 String* str = String::cast(js_value->value());
1376 if (index >= (uint32_t)str->length()) return false;
1377
1378 return true;
1379}
1380
1381
1382Object* FixedArray::get(int index) {
1383 ASSERT(index >= 0 && index < this->length());
1384 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1385}
1386
1387
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001388void FixedArray::set(int index, Smi* value) {
1389 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1390 int offset = kHeaderSize + index * kPointerSize;
1391 WRITE_FIELD(this, offset, value);
1392}
1393
1394
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395void FixedArray::set(int index, Object* value) {
1396 ASSERT(index >= 0 && index < this->length());
1397 int offset = kHeaderSize + index * kPointerSize;
1398 WRITE_FIELD(this, offset, value);
1399 WRITE_BARRIER(this, offset);
1400}
1401
1402
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001403WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1405 return UPDATE_WRITE_BARRIER;
1406}
1407
1408
1409void FixedArray::set(int index,
1410 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001411 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001412 ASSERT(index >= 0 && index < this->length());
1413 int offset = kHeaderSize + index * kPointerSize;
1414 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001415 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416}
1417
1418
1419void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1420 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001421 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1423}
1424
1425
1426void FixedArray::set_undefined(int index) {
1427 ASSERT(index >= 0 && index < this->length());
1428 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1429 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1430 Heap::undefined_value());
1431}
1432
1433
ager@chromium.org236ad962008-09-25 09:45:57 +00001434void FixedArray::set_null(int index) {
1435 ASSERT(index >= 0 && index < this->length());
1436 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1437 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1438}
1439
1440
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441void FixedArray::set_the_hole(int index) {
1442 ASSERT(index >= 0 && index < this->length());
1443 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1444 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1445}
1446
1447
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001448Object** FixedArray::data_start() {
1449 return HeapObject::RawField(this, kHeaderSize);
1450}
1451
1452
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001453bool DescriptorArray::IsEmpty() {
1454 ASSERT(this == Heap::empty_descriptor_array() ||
1455 this->length() > 2);
1456 return this == Heap::empty_descriptor_array();
1457}
1458
1459
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1461 Object* tmp = array->get(first);
1462 fast_set(array, first, array->get(second));
1463 fast_set(array, second, tmp);
1464}
1465
1466
1467int DescriptorArray::Search(String* name) {
1468 SLOW_ASSERT(IsSortedNoDuplicates());
1469
1470 // Check for empty descriptor array.
1471 int nof = number_of_descriptors();
1472 if (nof == 0) return kNotFound;
1473
1474 // Fast case: do linear search for small arrays.
1475 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001476 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001477 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001478 }
1479
1480 // Slow case: perform binary search.
1481 return BinarySearch(name, 0, nof - 1);
1482}
1483
1484
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485String* DescriptorArray::GetKey(int descriptor_number) {
1486 ASSERT(descriptor_number < number_of_descriptors());
1487 return String::cast(get(ToKeyIndex(descriptor_number)));
1488}
1489
1490
1491Object* DescriptorArray::GetValue(int descriptor_number) {
1492 ASSERT(descriptor_number < number_of_descriptors());
1493 return GetContentArray()->get(ToValueIndex(descriptor_number));
1494}
1495
1496
1497Smi* DescriptorArray::GetDetails(int descriptor_number) {
1498 ASSERT(descriptor_number < number_of_descriptors());
1499 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1500}
1501
1502
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001503PropertyType DescriptorArray::GetType(int descriptor_number) {
1504 ASSERT(descriptor_number < number_of_descriptors());
1505 return PropertyDetails(GetDetails(descriptor_number)).type();
1506}
1507
1508
1509int DescriptorArray::GetFieldIndex(int descriptor_number) {
1510 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1511}
1512
1513
1514JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1515 return JSFunction::cast(GetValue(descriptor_number));
1516}
1517
1518
1519Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1520 ASSERT(GetType(descriptor_number) == CALLBACKS);
1521 return GetValue(descriptor_number);
1522}
1523
1524
1525AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1526 ASSERT(GetType(descriptor_number) == CALLBACKS);
1527 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1528 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1529}
1530
1531
1532bool DescriptorArray::IsProperty(int descriptor_number) {
1533 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1534}
1535
1536
1537bool DescriptorArray::IsTransition(int descriptor_number) {
1538 PropertyType t = GetType(descriptor_number);
1539 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1540}
1541
1542
1543bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1544 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1545}
1546
1547
1548bool DescriptorArray::IsDontEnum(int descriptor_number) {
1549 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1550}
1551
1552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1554 desc->Init(GetKey(descriptor_number),
1555 GetValue(descriptor_number),
1556 GetDetails(descriptor_number));
1557}
1558
1559
1560void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1561 // Range check.
1562 ASSERT(descriptor_number < number_of_descriptors());
1563
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001564 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1566 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1567
1568 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1569 FixedArray* content_array = GetContentArray();
1570 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1571 fast_set(content_array, ToDetailsIndex(descriptor_number),
1572 desc->GetDetails().AsSmi());
1573}
1574
1575
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001576void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1577 Descriptor desc;
1578 src->Get(src_index, &desc);
1579 Set(index, &desc);
1580}
1581
1582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001583void DescriptorArray::Swap(int first, int second) {
1584 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1585 FixedArray* content_array = GetContentArray();
1586 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1587 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1588}
1589
1590
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001591bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001592 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593 if (!max_index_object->IsSmi()) return false;
1594 return 0 !=
1595 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1596}
1597
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001598uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001600 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 if (!max_index_object->IsSmi()) return 0;
1602 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1603 return value >> kRequiresSlowElementsTagSize;
1604}
1605
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001606void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001607 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001608}
1609
1610
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001611// ------------------------------------
1612// Cast operations
1613
1614
1615CAST_ACCESSOR(FixedArray)
1616CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001618CAST_ACCESSOR(JSFunctionResultCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001619CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001620CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001621CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622CAST_ACCESSOR(String)
1623CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001624CAST_ACCESSOR(SeqAsciiString)
1625CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001626CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001627CAST_ACCESSOR(ExternalString)
1628CAST_ACCESSOR(ExternalAsciiString)
1629CAST_ACCESSOR(ExternalTwoByteString)
1630CAST_ACCESSOR(JSObject)
1631CAST_ACCESSOR(Smi)
1632CAST_ACCESSOR(Failure)
1633CAST_ACCESSOR(HeapObject)
1634CAST_ACCESSOR(HeapNumber)
1635CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001636CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637CAST_ACCESSOR(SharedFunctionInfo)
1638CAST_ACCESSOR(Map)
1639CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001640CAST_ACCESSOR(GlobalObject)
1641CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001642CAST_ACCESSOR(JSGlobalObject)
1643CAST_ACCESSOR(JSBuiltinsObject)
1644CAST_ACCESSOR(Code)
1645CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001646CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001647CAST_ACCESSOR(Proxy)
1648CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001649CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001650CAST_ACCESSOR(ExternalArray)
1651CAST_ACCESSOR(ExternalByteArray)
1652CAST_ACCESSOR(ExternalUnsignedByteArray)
1653CAST_ACCESSOR(ExternalShortArray)
1654CAST_ACCESSOR(ExternalUnsignedShortArray)
1655CAST_ACCESSOR(ExternalIntArray)
1656CAST_ACCESSOR(ExternalUnsignedIntArray)
1657CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001658CAST_ACCESSOR(Struct)
1659
1660
1661#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1662 STRUCT_LIST(MAKE_STRUCT_CAST)
1663#undef MAKE_STRUCT_CAST
1664
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001665
1666template <typename Shape, typename Key>
1667HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668 ASSERT(obj->IsHashTable());
1669 return reinterpret_cast<HashTable*>(obj);
1670}
1671
1672
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001673SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1674SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1675
1676INT_ACCESSORS(PixelArray, length, kLengthOffset)
1677INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001678
1679
ager@chromium.orgac091b72010-05-05 07:34:42 +00001680SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001681
1682
1683uint32_t String::hash_field() {
1684 return READ_UINT32_FIELD(this, kHashFieldOffset);
1685}
1686
1687
1688void String::set_hash_field(uint32_t value) {
1689 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001690#if V8_HOST_ARCH_64_BIT
1691 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1692#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001693}
1694
1695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696bool String::Equals(String* other) {
1697 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001698 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1699 return false;
1700 }
1701 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702}
1703
1704
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001705Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001706 if (!StringShape(this).IsCons()) return this;
1707 ConsString* cons = ConsString::cast(this);
1708 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001709 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710}
1711
1712
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001713String* String::TryFlattenGetString(PretenureFlag pretenure) {
1714 Object* flat = TryFlatten(pretenure);
1715 return flat->IsFailure() ? this : String::cast(flat);
1716}
1717
1718
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001719uint16_t String::Get(int index) {
1720 ASSERT(index >= 0 && index < length());
1721 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001722 case kSeqStringTag | kAsciiStringTag:
1723 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1724 case kSeqStringTag | kTwoByteStringTag:
1725 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1726 case kConsStringTag | kAsciiStringTag:
1727 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001728 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001729 case kExternalStringTag | kAsciiStringTag:
1730 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1731 case kExternalStringTag | kTwoByteStringTag:
1732 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733 default:
1734 break;
1735 }
1736
1737 UNREACHABLE();
1738 return 0;
1739}
1740
1741
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001742void String::Set(int index, uint16_t value) {
1743 ASSERT(index >= 0 && index < length());
1744 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001745
ager@chromium.org5ec48922009-05-05 07:25:34 +00001746 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001747 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1748 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749}
1750
1751
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001752bool String::IsFlat() {
1753 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001754 case kConsStringTag: {
1755 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001756 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001757 return second->length() == 0;
1758 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001759 default:
1760 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761 }
1762}
1763
1764
ager@chromium.org7c537e22008-10-16 08:43:32 +00001765uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766 ASSERT(index >= 0 && index < length());
1767 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1768}
1769
1770
ager@chromium.org7c537e22008-10-16 08:43:32 +00001771void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1773 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1774 static_cast<byte>(value));
1775}
1776
1777
ager@chromium.org7c537e22008-10-16 08:43:32 +00001778Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001779 return FIELD_ADDR(this, kHeaderSize);
1780}
1781
1782
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001783char* SeqAsciiString::GetChars() {
1784 return reinterpret_cast<char*>(GetCharsAddress());
1785}
1786
1787
ager@chromium.org7c537e22008-10-16 08:43:32 +00001788Address SeqTwoByteString::GetCharsAddress() {
1789 return FIELD_ADDR(this, kHeaderSize);
1790}
1791
1792
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001793uc16* SeqTwoByteString::GetChars() {
1794 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1795}
1796
1797
ager@chromium.org7c537e22008-10-16 08:43:32 +00001798uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 ASSERT(index >= 0 && index < length());
1800 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1801}
1802
1803
ager@chromium.org7c537e22008-10-16 08:43:32 +00001804void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 ASSERT(index >= 0 && index < length());
1806 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1807}
1808
1809
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001810int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001811 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812}
1813
1814
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001815int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001816 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817}
1818
1819
ager@chromium.org870a0b62008-11-04 11:43:05 +00001820String* ConsString::first() {
1821 return String::cast(READ_FIELD(this, kFirstOffset));
1822}
1823
1824
1825Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826 return READ_FIELD(this, kFirstOffset);
1827}
1828
1829
ager@chromium.org870a0b62008-11-04 11:43:05 +00001830void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001832 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833}
1834
1835
ager@chromium.org870a0b62008-11-04 11:43:05 +00001836String* ConsString::second() {
1837 return String::cast(READ_FIELD(this, kSecondOffset));
1838}
1839
1840
1841Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001842 return READ_FIELD(this, kSecondOffset);
1843}
1844
1845
ager@chromium.org870a0b62008-11-04 11:43:05 +00001846void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001847 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001848 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849}
1850
1851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001852ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1853 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1854}
1855
1856
1857void ExternalAsciiString::set_resource(
1858 ExternalAsciiString::Resource* resource) {
1859 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1860}
1861
1862
1863ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1864 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1865}
1866
1867
1868void ExternalTwoByteString::set_resource(
1869 ExternalTwoByteString::Resource* resource) {
1870 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1871}
1872
1873
ager@chromium.orgac091b72010-05-05 07:34:42 +00001874void JSFunctionResultCache::MakeZeroSize() {
1875 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1876 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1877}
1878
1879
1880void JSFunctionResultCache::Clear() {
1881 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1882 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1883 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1884 MakeZeroSize();
1885}
1886
1887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888byte ByteArray::get(int index) {
1889 ASSERT(index >= 0 && index < this->length());
1890 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1891}
1892
1893
1894void ByteArray::set(int index, byte value) {
1895 ASSERT(index >= 0 && index < this->length());
1896 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1897}
1898
1899
1900int ByteArray::get_int(int index) {
1901 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1902 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1903}
1904
1905
1906ByteArray* ByteArray::FromDataStartAddress(Address address) {
1907 ASSERT_TAG_ALIGNED(address);
1908 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1909}
1910
1911
1912Address ByteArray::GetDataStartAddress() {
1913 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1914}
1915
1916
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001917uint8_t* PixelArray::external_pointer() {
1918 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1919 return reinterpret_cast<uint8_t*>(ptr);
1920}
1921
1922
1923void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1924 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1925 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1926}
1927
1928
1929uint8_t PixelArray::get(int index) {
1930 ASSERT((index >= 0) && (index < this->length()));
1931 uint8_t* ptr = external_pointer();
1932 return ptr[index];
1933}
1934
1935
1936void PixelArray::set(int index, uint8_t value) {
1937 ASSERT((index >= 0) && (index < this->length()));
1938 uint8_t* ptr = external_pointer();
1939 ptr[index] = value;
1940}
1941
1942
ager@chromium.org3811b432009-10-28 14:53:37 +00001943void* ExternalArray::external_pointer() {
1944 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1945 return reinterpret_cast<void*>(ptr);
1946}
1947
1948
1949void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1950 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1951 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1952}
1953
1954
1955int8_t ExternalByteArray::get(int index) {
1956 ASSERT((index >= 0) && (index < this->length()));
1957 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1958 return ptr[index];
1959}
1960
1961
1962void ExternalByteArray::set(int index, int8_t value) {
1963 ASSERT((index >= 0) && (index < this->length()));
1964 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1965 ptr[index] = value;
1966}
1967
1968
1969uint8_t ExternalUnsignedByteArray::get(int index) {
1970 ASSERT((index >= 0) && (index < this->length()));
1971 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1972 return ptr[index];
1973}
1974
1975
1976void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1977 ASSERT((index >= 0) && (index < this->length()));
1978 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1979 ptr[index] = value;
1980}
1981
1982
1983int16_t ExternalShortArray::get(int index) {
1984 ASSERT((index >= 0) && (index < this->length()));
1985 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1986 return ptr[index];
1987}
1988
1989
1990void ExternalShortArray::set(int index, int16_t value) {
1991 ASSERT((index >= 0) && (index < this->length()));
1992 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1993 ptr[index] = value;
1994}
1995
1996
1997uint16_t ExternalUnsignedShortArray::get(int index) {
1998 ASSERT((index >= 0) && (index < this->length()));
1999 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2000 return ptr[index];
2001}
2002
2003
2004void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2005 ASSERT((index >= 0) && (index < this->length()));
2006 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2007 ptr[index] = value;
2008}
2009
2010
2011int32_t ExternalIntArray::get(int index) {
2012 ASSERT((index >= 0) && (index < this->length()));
2013 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2014 return ptr[index];
2015}
2016
2017
2018void ExternalIntArray::set(int index, int32_t value) {
2019 ASSERT((index >= 0) && (index < this->length()));
2020 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2021 ptr[index] = value;
2022}
2023
2024
2025uint32_t ExternalUnsignedIntArray::get(int index) {
2026 ASSERT((index >= 0) && (index < this->length()));
2027 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2028 return ptr[index];
2029}
2030
2031
2032void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2033 ASSERT((index >= 0) && (index < this->length()));
2034 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2035 ptr[index] = value;
2036}
2037
2038
2039float ExternalFloatArray::get(int index) {
2040 ASSERT((index >= 0) && (index < this->length()));
2041 float* ptr = static_cast<float*>(external_pointer());
2042 return ptr[index];
2043}
2044
2045
2046void ExternalFloatArray::set(int index, float value) {
2047 ASSERT((index >= 0) && (index < this->length()));
2048 float* ptr = static_cast<float*>(external_pointer());
2049 ptr[index] = value;
2050}
2051
2052
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002053int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002054 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2055}
2056
2057
2058int Map::inobject_properties() {
2059 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002060}
2061
2062
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002063int Map::pre_allocated_property_fields() {
2064 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2065}
2066
2067
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068int HeapObject::SizeFromMap(Map* map) {
2069 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002070 // Only inline the most frequent cases.
2071 if (instance_type == JS_OBJECT_TYPE ||
2072 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2073 (kStringTag | kConsStringTag) ||
2074 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002075 if (instance_type == FIXED_ARRAY_TYPE) {
2076 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2077 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002078 if (instance_type == BYTE_ARRAY_TYPE) {
2079 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2080 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002081 // Otherwise do the general size computation.
2082 return SlowSizeFromMap(map);
2083}
2084
2085
2086void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002087 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002088 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089 ASSERT(0 <= value && value < 256);
2090 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2091}
2092
2093
ager@chromium.org7c537e22008-10-16 08:43:32 +00002094void Map::set_inobject_properties(int value) {
2095 ASSERT(0 <= value && value < 256);
2096 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2097}
2098
2099
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002100void Map::set_pre_allocated_property_fields(int value) {
2101 ASSERT(0 <= value && value < 256);
2102 WRITE_BYTE_FIELD(this,
2103 kPreAllocatedPropertyFieldsOffset,
2104 static_cast<byte>(value));
2105}
2106
2107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108InstanceType Map::instance_type() {
2109 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2110}
2111
2112
2113void Map::set_instance_type(InstanceType value) {
2114 ASSERT(0 <= value && value < 256);
2115 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2116}
2117
2118
2119int Map::unused_property_fields() {
2120 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2121}
2122
2123
2124void Map::set_unused_property_fields(int value) {
2125 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2126}
2127
2128
2129byte Map::bit_field() {
2130 return READ_BYTE_FIELD(this, kBitFieldOffset);
2131}
2132
2133
2134void Map::set_bit_field(byte value) {
2135 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2136}
2137
2138
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002139byte Map::bit_field2() {
2140 return READ_BYTE_FIELD(this, kBitField2Offset);
2141}
2142
2143
2144void Map::set_bit_field2(byte value) {
2145 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2146}
2147
2148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149void Map::set_non_instance_prototype(bool value) {
2150 if (value) {
2151 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2152 } else {
2153 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2154 }
2155}
2156
2157
2158bool Map::has_non_instance_prototype() {
2159 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2160}
2161
2162
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002163void Map::set_function_with_prototype(bool value) {
2164 if (value) {
2165 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2166 } else {
2167 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2168 }
2169}
2170
2171
2172bool Map::function_with_prototype() {
2173 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2174}
2175
2176
ager@chromium.org870a0b62008-11-04 11:43:05 +00002177void Map::set_is_access_check_needed(bool access_check_needed) {
2178 if (access_check_needed) {
2179 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2180 } else {
2181 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2182 }
2183}
2184
2185
2186bool Map::is_access_check_needed() {
2187 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2188}
2189
2190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191Code::Flags Code::flags() {
2192 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2193}
2194
2195
2196void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002197 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198 // Make sure that all call stubs have an arguments count.
2199 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2200 ExtractArgumentsCountFromFlags(flags) >= 0);
2201 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2202}
2203
2204
2205Code::Kind Code::kind() {
2206 return ExtractKindFromFlags(flags());
2207}
2208
2209
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002210InLoopFlag Code::ic_in_loop() {
2211 return ExtractICInLoopFromFlags(flags());
2212}
2213
2214
kasper.lund7276f142008-07-30 08:49:36 +00002215InlineCacheState Code::ic_state() {
2216 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002217 // Only allow uninitialized or debugger states for non-IC code
2218 // objects. This is used in the debugger to determine whether or not
2219 // a call to code object has been replaced with a debug break call.
2220 ASSERT(is_inline_cache_stub() ||
2221 result == UNINITIALIZED ||
2222 result == DEBUG_BREAK ||
2223 result == DEBUG_PREPARE_STEP_IN);
2224 return result;
2225}
2226
2227
2228PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002229 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230 return ExtractTypeFromFlags(flags());
2231}
2232
2233
2234int Code::arguments_count() {
2235 ASSERT(is_call_stub() || kind() == STUB);
2236 return ExtractArgumentsCountFromFlags(flags());
2237}
2238
2239
2240CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002241 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002242 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2243 kStubMajorKeyOffset));
2244}
2245
2246
2247void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002248 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002249 ASSERT(0 <= major && major < 256);
2250 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
2254bool Code::is_inline_cache_stub() {
2255 Kind kind = this->kind();
2256 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2257}
2258
2259
2260Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002261 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002262 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002263 PropertyType type,
2264 int argc) {
2265 // Compute the bit mask.
2266 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002267 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002268 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 bits |= type << kFlagsTypeShift;
2270 bits |= argc << kFlagsArgumentsCountShift;
2271 // Cast to flags and validate result before returning it.
2272 Flags result = static_cast<Flags>(bits);
2273 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002274 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002275 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276 ASSERT(ExtractTypeFromFlags(result) == type);
2277 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2278 return result;
2279}
2280
2281
2282Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2283 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002284 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002286 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287}
2288
2289
2290Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2291 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2292 return static_cast<Kind>(bits);
2293}
2294
2295
kasper.lund7276f142008-07-30 08:49:36 +00002296InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2297 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298 return static_cast<InlineCacheState>(bits);
2299}
2300
2301
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002302InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2303 int bits = (flags & kFlagsICInLoopMask);
2304 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2305}
2306
2307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002308PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2309 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2310 return static_cast<PropertyType>(bits);
2311}
2312
2313
2314int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2315 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2316}
2317
2318
2319Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2320 int bits = flags & ~kFlagsTypeMask;
2321 return static_cast<Flags>(bits);
2322}
2323
2324
ager@chromium.org8bb60582008-12-11 12:02:20 +00002325Code* Code::GetCodeFromTargetAddress(Address address) {
2326 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2327 // GetCodeFromTargetAddress might be called when marking objects during mark
2328 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2329 // Code::cast. Code::cast does not work when the object's map is
2330 // marked.
2331 Code* result = reinterpret_cast<Code*>(code);
2332 return result;
2333}
2334
2335
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002336Object* Map::prototype() {
2337 return READ_FIELD(this, kPrototypeOffset);
2338}
2339
2340
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002341void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342 ASSERT(value->IsNull() || value->IsJSObject());
2343 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002344 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002345}
2346
2347
2348ACCESSORS(Map, instance_descriptors, DescriptorArray,
2349 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002350ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351ACCESSORS(Map, constructor, Object, kConstructorOffset)
2352
2353ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2354ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2355
2356ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2357ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002358ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002360ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361
2362ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2363ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2364ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2365ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2366ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002367ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368
2369ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2370ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2371ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2372
2373ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2374ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2375ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2376ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2377ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2378ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2379
2380ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2381ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2382
2383ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2384ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2385
2386ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2387ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2389 kPropertyAccessorsOffset)
2390ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2391 kPrototypeTemplateOffset)
2392ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2393ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2394 kNamedPropertyHandlerOffset)
2395ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2396 kIndexedPropertyHandlerOffset)
2397ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2398 kInstanceTemplateOffset)
2399ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2400ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2402 kInstanceCallHandlerOffset)
2403ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2404 kAccessCheckInfoOffset)
2405ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2406
2407ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002408ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2409 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410
2411ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2412ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2413
2414ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2415
2416ACCESSORS(Script, source, Object, kSourceOffset)
2417ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002418ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002419ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2420ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002421ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002422ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2424ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002425ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002426ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002427ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002428ACCESSORS(Script, eval_from_instructions_offset, Smi,
2429 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002431#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2433ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2434ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2435ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2436
2437ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2438ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2439ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2440ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002441#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442
2443ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002444ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2446 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002447ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002448ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2449ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002450ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002451ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2452 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453
2454BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2455 kHiddenPrototypeBit)
2456BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2457BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2458 kNeedsAccessCheckBit)
2459BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2460 kIsExpressionBit)
2461BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2462 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002463BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002464 has_only_simple_this_property_assignments,
2465 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002466BOOL_ACCESSORS(SharedFunctionInfo,
2467 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002468 try_full_codegen,
2469 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002470
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002471#if V8_HOST_ARCH_32_BIT
2472SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2473SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002475SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002476 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002477SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2478SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002479 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002480SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2481SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002483SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002484 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002485SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002486 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002487#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002488
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002489#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2490 int holder::name() { \
2491 int value = READ_INT_FIELD(this, offset); \
2492 ASSERT(kHeapObjectTag == 1); \
2493 ASSERT((value & kHeapObjectTag) == 0); \
2494 return value >> 1; \
2495 } \
2496 void holder::set_##name(int value) { \
2497 ASSERT(kHeapObjectTag == 1); \
2498 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2499 (value & 0xC0000000) == 0x000000000); \
2500 WRITE_INT_FIELD(this, \
2501 offset, \
2502 (value << 1) & ~kHeapObjectTag); \
2503 }
2504
2505#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2506 INT_ACCESSORS(holder, name, offset)
2507
2508
2509
2510PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2511PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2512 kFormalParameterCountOffset)
2513
2514PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2515 kExpectedNofPropertiesOffset)
2516PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2517
2518PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2519 kStartPositionAndTypeOffset)
2520PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2521
2522PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2523 kFunctionTokenPositionOffset)
2524PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2525 kCompilerHintsOffset)
2526
2527PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2528 kThisPropertyAssignmentsCountOffset)
2529#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002530
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002531ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2532ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2533
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002534bool Script::HasValidSource() {
2535 Object* src = this->source();
2536 if (!src->IsString()) return true;
2537 String* src_str = String::cast(src);
2538 if (!StringShape(src_str).IsExternal()) return true;
2539 if (src_str->IsAsciiRepresentation()) {
2540 return ExternalAsciiString::cast(src)->resource() != NULL;
2541 } else if (src_str->IsTwoByteRepresentation()) {
2542 return ExternalTwoByteString::cast(src)->resource() != NULL;
2543 }
2544 return true;
2545}
2546
2547
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002548void SharedFunctionInfo::DontAdaptArguments() {
2549 ASSERT(code()->kind() == Code::BUILTIN);
2550 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2551}
2552
2553
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002554int SharedFunctionInfo::start_position() {
2555 return start_position_and_type() >> kStartPositionShift;
2556}
2557
2558
2559void SharedFunctionInfo::set_start_position(int start_position) {
2560 set_start_position_and_type((start_position << kStartPositionShift)
2561 | (start_position_and_type() & ~kStartPositionMask));
2562}
2563
2564
2565Code* SharedFunctionInfo::code() {
2566 return Code::cast(READ_FIELD(this, kCodeOffset));
2567}
2568
2569
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002570void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002571 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002572 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002573}
2574
2575
2576bool SharedFunctionInfo::is_compiled() {
2577 // TODO(1242782): Create a code kind for uncompiled code.
2578 return code()->kind() != Code::STUB;
2579}
2580
2581
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002582bool SharedFunctionInfo::IsApiFunction() {
2583 return function_data()->IsFunctionTemplateInfo();
2584}
2585
2586
2587FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2588 ASSERT(IsApiFunction());
2589 return FunctionTemplateInfo::cast(function_data());
2590}
2591
2592
2593bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002594 return function_data()->IsSmi();
2595}
2596
2597
2598int SharedFunctionInfo::custom_call_generator_id() {
2599 ASSERT(HasCustomCallGenerator());
2600 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002601}
2602
2603
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002604bool JSFunction::IsBuiltin() {
2605 return context()->global()->IsJSBuiltinsObject();
2606}
2607
2608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609Code* JSFunction::code() {
2610 return shared()->code();
2611}
2612
2613
2614void JSFunction::set_code(Code* value) {
2615 shared()->set_code(value);
2616}
2617
2618
2619Context* JSFunction::context() {
2620 return Context::cast(READ_FIELD(this, kContextOffset));
2621}
2622
2623
2624Object* JSFunction::unchecked_context() {
2625 return READ_FIELD(this, kContextOffset);
2626}
2627
2628
2629void JSFunction::set_context(Object* value) {
2630 ASSERT(value == Heap::undefined_value() || value->IsContext());
2631 WRITE_FIELD(this, kContextOffset, value);
2632 WRITE_BARRIER(this, kContextOffset);
2633}
2634
2635ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2636 kPrototypeOrInitialMapOffset)
2637
2638
2639Map* JSFunction::initial_map() {
2640 return Map::cast(prototype_or_initial_map());
2641}
2642
2643
2644void JSFunction::set_initial_map(Map* value) {
2645 set_prototype_or_initial_map(value);
2646}
2647
2648
2649bool JSFunction::has_initial_map() {
2650 return prototype_or_initial_map()->IsMap();
2651}
2652
2653
2654bool JSFunction::has_instance_prototype() {
2655 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2656}
2657
2658
2659bool JSFunction::has_prototype() {
2660 return map()->has_non_instance_prototype() || has_instance_prototype();
2661}
2662
2663
2664Object* JSFunction::instance_prototype() {
2665 ASSERT(has_instance_prototype());
2666 if (has_initial_map()) return initial_map()->prototype();
2667 // When there is no initial map and the prototype is a JSObject, the
2668 // initial map field is used for the prototype field.
2669 return prototype_or_initial_map();
2670}
2671
2672
2673Object* JSFunction::prototype() {
2674 ASSERT(has_prototype());
2675 // If the function's prototype property has been set to a non-JSObject
2676 // value, that value is stored in the constructor field of the map.
2677 if (map()->has_non_instance_prototype()) return map()->constructor();
2678 return instance_prototype();
2679}
2680
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002681bool JSFunction::should_have_prototype() {
2682 return map()->function_with_prototype();
2683}
2684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002685
2686bool JSFunction::is_compiled() {
2687 return shared()->is_compiled();
2688}
2689
2690
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002691int JSFunction::NumberOfLiterals() {
2692 return literals()->length();
2693}
2694
2695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002696Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2697 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002698 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002699}
2700
2701
2702void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2703 Object* value) {
2704 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002705 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2706 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2707}
2708
2709
2710Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2711 ASSERT(0 <= id && id < kJSBuiltinsCount);
2712 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2713}
2714
2715
2716void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2717 Code* value) {
2718 ASSERT(0 <= id && id < kJSBuiltinsCount);
2719 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2720 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002721}
2722
2723
2724Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002725 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726}
2727
2728
2729void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002730 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002731}
2732
2733
2734void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2735 visitor->VisitExternalReference(
2736 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2737}
2738
2739
2740ACCESSORS(JSValue, value, Object, kValueOffset)
2741
2742
2743JSValue* JSValue::cast(Object* obj) {
2744 ASSERT(obj->IsJSValue());
2745 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2746 return reinterpret_cast<JSValue*>(obj);
2747}
2748
2749
2750INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2751INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2752INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2753
2754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002755byte* Code::instruction_start() {
2756 return FIELD_ADDR(this, kHeaderSize);
2757}
2758
2759
2760int Code::body_size() {
2761 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2762}
2763
2764
2765byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002766 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002767}
2768
2769
2770byte* Code::entry() {
2771 return instruction_start();
2772}
2773
2774
2775bool Code::contains(byte* pc) {
2776 return (instruction_start() <= pc) &&
2777 (pc < instruction_start() + instruction_size());
2778}
2779
2780
2781byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002782 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783}
2784
2785
2786ACCESSORS(JSArray, length, Object, kLengthOffset)
2787
2788
ager@chromium.org236ad962008-09-25 09:45:57 +00002789ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002790
2791
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002792JSRegExp::Type JSRegExp::TypeTag() {
2793 Object* data = this->data();
2794 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2795 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2796 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002797}
2798
2799
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002800int JSRegExp::CaptureCount() {
2801 switch (TypeTag()) {
2802 case ATOM:
2803 return 0;
2804 case IRREGEXP:
2805 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2806 default:
2807 UNREACHABLE();
2808 return -1;
2809 }
2810}
2811
2812
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002813JSRegExp::Flags JSRegExp::GetFlags() {
2814 ASSERT(this->data()->IsFixedArray());
2815 Object* data = this->data();
2816 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2817 return Flags(smi->value());
2818}
2819
2820
2821String* JSRegExp::Pattern() {
2822 ASSERT(this->data()->IsFixedArray());
2823 Object* data = this->data();
2824 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2825 return pattern;
2826}
2827
2828
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002829Object* JSRegExp::DataAt(int index) {
2830 ASSERT(TypeTag() != NOT_COMPILED);
2831 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002832}
2833
2834
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002835void JSRegExp::SetDataAt(int index, Object* value) {
2836 ASSERT(TypeTag() != NOT_COMPILED);
2837 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2838 FixedArray::cast(data())->set(index, value);
2839}
2840
2841
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002842JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002843 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002844 if (array->IsFixedArray()) {
2845 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2846 if (array->map() == Heap::fixed_array_map()) {
2847 return FAST_ELEMENTS;
2848 }
2849 ASSERT(array->IsDictionary());
2850 return DICTIONARY_ELEMENTS;
2851 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002852 if (array->IsExternalArray()) {
2853 switch (array->map()->instance_type()) {
2854 case EXTERNAL_BYTE_ARRAY_TYPE:
2855 return EXTERNAL_BYTE_ELEMENTS;
2856 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2857 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2858 case EXTERNAL_SHORT_ARRAY_TYPE:
2859 return EXTERNAL_SHORT_ELEMENTS;
2860 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2861 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2862 case EXTERNAL_INT_ARRAY_TYPE:
2863 return EXTERNAL_INT_ELEMENTS;
2864 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2865 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2866 default:
2867 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2868 return EXTERNAL_FLOAT_ELEMENTS;
2869 }
2870 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002871 ASSERT(array->IsPixelArray());
2872 return PIXEL_ELEMENTS;
2873}
2874
2875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002877 return GetElementsKind() == FAST_ELEMENTS;
2878}
2879
2880
2881bool JSObject::HasDictionaryElements() {
2882 return GetElementsKind() == DICTIONARY_ELEMENTS;
2883}
2884
2885
2886bool JSObject::HasPixelElements() {
2887 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002888}
2889
2890
ager@chromium.org3811b432009-10-28 14:53:37 +00002891bool JSObject::HasExternalArrayElements() {
2892 return (HasExternalByteElements() ||
2893 HasExternalUnsignedByteElements() ||
2894 HasExternalShortElements() ||
2895 HasExternalUnsignedShortElements() ||
2896 HasExternalIntElements() ||
2897 HasExternalUnsignedIntElements() ||
2898 HasExternalFloatElements());
2899}
2900
2901
2902bool JSObject::HasExternalByteElements() {
2903 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2904}
2905
2906
2907bool JSObject::HasExternalUnsignedByteElements() {
2908 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2909}
2910
2911
2912bool JSObject::HasExternalShortElements() {
2913 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2914}
2915
2916
2917bool JSObject::HasExternalUnsignedShortElements() {
2918 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2919}
2920
2921
2922bool JSObject::HasExternalIntElements() {
2923 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2924}
2925
2926
2927bool JSObject::HasExternalUnsignedIntElements() {
2928 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2929}
2930
2931
2932bool JSObject::HasExternalFloatElements() {
2933 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2934}
2935
2936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002937bool JSObject::HasNamedInterceptor() {
2938 return map()->has_named_interceptor();
2939}
2940
2941
2942bool JSObject::HasIndexedInterceptor() {
2943 return map()->has_indexed_interceptor();
2944}
2945
2946
ager@chromium.org5c838252010-02-19 08:53:10 +00002947bool JSObject::AllowsSetElementsLength() {
2948 bool result = elements()->IsFixedArray();
2949 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2950 return result;
2951}
2952
2953
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002954StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002955 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002956 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957}
2958
2959
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002960NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002961 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002962 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002963}
2964
2965
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002966bool String::IsHashFieldComputed(uint32_t field) {
2967 return (field & kHashNotComputedMask) == 0;
2968}
2969
2970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002971bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002972 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973}
2974
2975
2976uint32_t String::Hash() {
2977 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002978 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002979 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002980 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002981 return ComputeAndSetHash();
2982}
2983
2984
ager@chromium.org7c537e22008-10-16 08:43:32 +00002985StringHasher::StringHasher(int length)
2986 : length_(length),
2987 raw_running_hash_(0),
2988 array_index_(0),
2989 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2990 is_first_char_(true),
2991 is_valid_(true) { }
2992
2993
2994bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002995 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002996}
2997
2998
2999void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003000 // Use the Jenkins one-at-a-time hash function to update the hash
3001 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003002 raw_running_hash_ += c;
3003 raw_running_hash_ += (raw_running_hash_ << 10);
3004 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003005 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003006 if (is_array_index_) {
3007 if (c < '0' || c > '9') {
3008 is_array_index_ = false;
3009 } else {
3010 int d = c - '0';
3011 if (is_first_char_) {
3012 is_first_char_ = false;
3013 if (c == '0' && length_ > 1) {
3014 is_array_index_ = false;
3015 return;
3016 }
3017 }
3018 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3019 is_array_index_ = false;
3020 } else {
3021 array_index_ = array_index_ * 10 + d;
3022 }
3023 }
3024 }
3025}
3026
3027
3028void StringHasher::AddCharacterNoIndex(uc32 c) {
3029 ASSERT(!is_array_index());
3030 raw_running_hash_ += c;
3031 raw_running_hash_ += (raw_running_hash_ << 10);
3032 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3033}
3034
3035
3036uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003037 // Get the calculated raw hash value and do some more bit ops to distribute
3038 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003039 uint32_t result = raw_running_hash_;
3040 result += (result << 3);
3041 result ^= (result >> 11);
3042 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003043 if (result == 0) {
3044 result = 27;
3045 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003046 return result;
3047}
3048
3049
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003050bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003051 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003052 if (IsHashFieldComputed(field) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053 return SlowAsArrayIndex(index);
3054}
3055
3056
3057Object* JSObject::GetPrototype() {
3058 return JSObject::cast(this)->map()->prototype();
3059}
3060
3061
3062PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3063 return GetPropertyAttributeWithReceiver(this, key);
3064}
3065
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003066// TODO(504): this may be useful in other places too where JSGlobalProxy
3067// is used.
3068Object* JSObject::BypassGlobalProxy() {
3069 if (IsJSGlobalProxy()) {
3070 Object* proto = GetPrototype();
3071 if (proto->IsNull()) return Heap::undefined_value();
3072 ASSERT(proto->IsJSGlobalObject());
3073 return proto;
3074 }
3075 return this;
3076}
3077
3078
3079bool JSObject::HasHiddenPropertiesObject() {
3080 ASSERT(!IsJSGlobalProxy());
3081 return GetPropertyAttributePostInterceptor(this,
3082 Heap::hidden_symbol(),
3083 false) != ABSENT;
3084}
3085
3086
3087Object* JSObject::GetHiddenPropertiesObject() {
3088 ASSERT(!IsJSGlobalProxy());
3089 PropertyAttributes attributes;
3090 return GetLocalPropertyPostInterceptor(this,
3091 Heap::hidden_symbol(),
3092 &attributes);
3093}
3094
3095
3096Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3097 ASSERT(!IsJSGlobalProxy());
3098 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3099 hidden_obj,
3100 DONT_ENUM);
3101}
3102
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003103
3104bool JSObject::HasElement(uint32_t index) {
3105 return HasElementWithReceiver(this, index);
3106}
3107
3108
3109bool AccessorInfo::all_can_read() {
3110 return BooleanBit::get(flag(), kAllCanReadBit);
3111}
3112
3113
3114void AccessorInfo::set_all_can_read(bool value) {
3115 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3116}
3117
3118
3119bool AccessorInfo::all_can_write() {
3120 return BooleanBit::get(flag(), kAllCanWriteBit);
3121}
3122
3123
3124void AccessorInfo::set_all_can_write(bool value) {
3125 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3126}
3127
3128
ager@chromium.org870a0b62008-11-04 11:43:05 +00003129bool AccessorInfo::prohibits_overwriting() {
3130 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3131}
3132
3133
3134void AccessorInfo::set_prohibits_overwriting(bool value) {
3135 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3136}
3137
3138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139PropertyAttributes AccessorInfo::property_attributes() {
3140 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3141}
3142
3143
3144void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3145 ASSERT(AttributesField::is_valid(attributes));
3146 int rest_value = flag()->value() & ~AttributesField::mask();
3147 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3148}
3149
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003150template<typename Shape, typename Key>
3151void Dictionary<Shape, Key>::SetEntry(int entry,
3152 Object* key,
3153 Object* value,
3154 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003155 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003156 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003157 AssertNoAllocation no_gc;
3158 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003159 FixedArray::set(index, key, mode);
3160 FixedArray::set(index+1, value, mode);
3161 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003162}
3163
3164
3165void Map::ClearCodeCache() {
3166 // No write barrier is needed since empty_fixed_array is not in new space.
3167 // Please note this function is used during marking:
3168 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003169 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3170 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003171}
3172
3173
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003174void JSArray::EnsureSize(int required_size) {
3175 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003176 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003177 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3178 if (elts->length() < required_size) {
3179 // Doubling in size would be overkill, but leave some slack to avoid
3180 // constantly growing.
3181 Expand(required_size + (required_size >> 3));
3182 // It's a performance benefit to keep a frequently used array in new-space.
3183 } else if (!Heap::new_space()->Contains(elts) &&
3184 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3185 // Expand will allocate a new backing store in new space even if the size
3186 // we asked for isn't larger than what we had before.
3187 Expand(required_size);
3188 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003189}
3190
3191
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003192void JSArray::set_length(Smi* length) {
3193 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3194}
3195
3196
ager@chromium.org7c537e22008-10-16 08:43:32 +00003197void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003198 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003199 set_elements(storage);
3200}
3201
3202
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003203Object* FixedArray::Copy() {
3204 if (length() == 0) return this;
3205 return Heap::CopyFixedArray(this);
3206}
3207
3208
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003209#undef CAST_ACCESSOR
3210#undef INT_ACCESSORS
3211#undef SMI_ACCESSORS
3212#undef ACCESSORS
3213#undef FIELD_ADDR
3214#undef READ_FIELD
3215#undef WRITE_FIELD
3216#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003217#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003218#undef READ_MEMADDR_FIELD
3219#undef WRITE_MEMADDR_FIELD
3220#undef READ_DOUBLE_FIELD
3221#undef WRITE_DOUBLE_FIELD
3222#undef READ_INT_FIELD
3223#undef WRITE_INT_FIELD
3224#undef READ_SHORT_FIELD
3225#undef WRITE_SHORT_FIELD
3226#undef READ_BYTE_FIELD
3227#undef WRITE_BYTE_FIELD
3228
3229
3230} } // namespace v8::internal
3231
3232#endif // V8_OBJECTS_INL_H_