blob: d82d73ec50108cd6526799bc30601a8ccf364681 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000056PropertyDetails PropertyDetails::AsDeleted() {
57 PropertyDetails d(DONT_ENUM, NORMAL);
58 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
59 return PropertyDetails(smi);
60}
61
62
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 ASSERT(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 }
68
69
70#define INT_ACCESSORS(holder, name, offset) \
71 int holder::name() { return READ_INT_FIELD(this, offset); } \
72 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
73
74
75#define ACCESSORS(holder, name, type, offset) \
76 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000077 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 }
81
82
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084#define SMI_ACCESSORS(holder, name, offset) \
85 int holder::name() { \
86 Object* value = READ_FIELD(this, offset); \
87 return Smi::cast(value)->value(); \
88 } \
89 void holder::set_##name(int value) { \
90 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
91 }
92
93
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000094#define BOOL_GETTER(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98
99
100#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104 void holder::set_##name(bool value) { \
105 set_##field(BooleanBit::set(field(), offset, value)); \
106 }
107
108
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000109bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
110 // There is a constraint on the object; check.
111 if (!this->IsJSObject()) return false;
112 // Fetch the constructor function of the object.
113 Object* cons_obj = JSObject::cast(this)->map()->constructor();
114 if (!cons_obj->IsJSFunction()) return false;
115 JSFunction* fun = JSFunction::cast(cons_obj);
116 // Iterate through the chain of inheriting function templates to
117 // see if the required one occurs.
118 for (Object* type = fun->shared()->function_data();
119 type->IsFunctionTemplateInfo();
120 type = FunctionTemplateInfo::cast(type)->parent_template()) {
121 if (type == expected) return true;
122 }
123 // Didn't find the required type in the inheritance chain.
124 return false;
125}
126
127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128bool Object::IsSmi() {
129 return HAS_SMI_TAG(this);
130}
131
132
133bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000134 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135}
136
137
138bool Object::IsHeapNumber() {
139 return Object::IsHeapObject()
140 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
141}
142
143
144bool Object::IsString() {
145 return Object::IsHeapObject()
146 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
147}
148
149
ager@chromium.org870a0b62008-11-04 11:43:05 +0000150bool Object::IsSymbol() {
151 if (!this->IsHeapObject()) return false;
152 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000153 // Because the symbol tag is non-zero and no non-string types have the
154 // symbol bit set we can test for symbols with a very simple test
155 // operation.
156 ASSERT(kSymbolTag != 0);
157 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
158 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159}
160
161
162bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000163 if (!this->IsHeapObject()) return false;
164 uint32_t type = HeapObject::cast(this)->map()->instance_type();
165 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
166 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167}
168
169
ager@chromium.org870a0b62008-11-04 11:43:05 +0000170bool Object::IsSeqString() {
171 if (!IsString()) return false;
172 return StringShape(String::cast(this)).IsSequential();
173}
174
175
176bool Object::IsSeqAsciiString() {
177 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000178 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000179 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180}
181
182
183bool Object::IsSeqTwoByteString() {
184 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000185 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000186 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187}
188
189
190bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191 if (!IsString()) return false;
192 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000198 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000199 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200}
201
202
203bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000204 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000205 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000206 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207}
208
209
ager@chromium.org870a0b62008-11-04 11:43:05 +0000210StringShape::StringShape(String* str)
211 : type_(str->map()->instance_type()) {
212 set_valid();
213 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217StringShape::StringShape(Map* map)
218 : type_(map->instance_type()) {
219 set_valid();
220 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221}
222
223
ager@chromium.org870a0b62008-11-04 11:43:05 +0000224StringShape::StringShape(InstanceType t)
225 : type_(static_cast<uint32_t>(t)) {
226 set_valid();
227 ASSERT((type_ & kIsNotStringMask) == kStringTag);
228}
229
230
231bool StringShape::IsSymbol() {
232 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000233 ASSERT(kSymbolTag != 0);
234 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235}
236
237
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238bool String::IsAsciiRepresentation() {
239 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240 if ((type & kStringRepresentationMask) == kConsStringTag &&
241 ConsString::cast(this)->second()->length() == 0) {
242 return ConsString::cast(this)->first()->IsAsciiRepresentation();
243 }
244 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245}
246
247
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248bool String::IsTwoByteRepresentation() {
249 uint32_t type = map()->instance_type();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000250 if ((type & kStringRepresentationMask) == kConsStringTag &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 ConsString::cast(this)->second()->length() == 0) {
252 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
253 }
254 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000255}
256
257
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000258bool String::IsExternalTwoByteStringWithAsciiChars() {
259 if (!IsExternalTwoByteString()) return false;
260 const uc16* data = ExternalTwoByteString::cast(this)->resource()->data();
261 for (int i = 0, len = length(); i < len; i++) {
262 if (data[i] > kMaxAsciiCharCode) return false;
263 }
264 return true;
265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268bool StringShape::IsCons() {
269 return (type_ & kStringRepresentationMask) == kConsStringTag;
270}
271
272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273bool StringShape::IsExternal() {
274 return (type_ & kStringRepresentationMask) == kExternalStringTag;
275}
276
277
278bool StringShape::IsSequential() {
279 return (type_ & kStringRepresentationMask) == kSeqStringTag;
280}
281
282
283StringRepresentationTag StringShape::representation_tag() {
284 uint32_t tag = (type_ & kStringRepresentationMask);
285 return static_cast<StringRepresentationTag>(tag);
286}
287
288
289uint32_t StringShape::full_representation_tag() {
290 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
291}
292
293
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000294STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
295 Internals::kFullStringRepresentationMask);
296
297
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298bool StringShape::IsSequentialAscii() {
299 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305}
306
307
308bool StringShape::IsExternalAscii() {
309 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315}
316
317
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000318STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
319 Internals::kExternalTwoByteRepresentationTag);
320
321
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000322uc32 FlatStringReader::Get(int index) {
323 ASSERT(0 <= index && index <= length_);
324 if (is_ascii_) {
325 return static_cast<const byte*>(start_)[index];
326 } else {
327 return static_cast<const uc16*>(start_)[index];
328 }
329}
330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332bool Object::IsNumber() {
333 return IsSmi() || IsHeapNumber();
334}
335
336
337bool Object::IsByteArray() {
338 return Object::IsHeapObject()
339 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
340}
341
342
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000343bool Object::IsPixelArray() {
344 return Object::IsHeapObject() &&
345 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
346}
347
348
ager@chromium.org3811b432009-10-28 14:53:37 +0000349bool Object::IsExternalArray() {
350 if (!Object::IsHeapObject())
351 return false;
352 InstanceType instance_type =
353 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000354 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
355 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000356}
357
358
359bool Object::IsExternalByteArray() {
360 return Object::IsHeapObject() &&
361 HeapObject::cast(this)->map()->instance_type() ==
362 EXTERNAL_BYTE_ARRAY_TYPE;
363}
364
365
366bool Object::IsExternalUnsignedByteArray() {
367 return Object::IsHeapObject() &&
368 HeapObject::cast(this)->map()->instance_type() ==
369 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
370}
371
372
373bool Object::IsExternalShortArray() {
374 return Object::IsHeapObject() &&
375 HeapObject::cast(this)->map()->instance_type() ==
376 EXTERNAL_SHORT_ARRAY_TYPE;
377}
378
379
380bool Object::IsExternalUnsignedShortArray() {
381 return Object::IsHeapObject() &&
382 HeapObject::cast(this)->map()->instance_type() ==
383 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
384}
385
386
387bool Object::IsExternalIntArray() {
388 return Object::IsHeapObject() &&
389 HeapObject::cast(this)->map()->instance_type() ==
390 EXTERNAL_INT_ARRAY_TYPE;
391}
392
393
394bool Object::IsExternalUnsignedIntArray() {
395 return Object::IsHeapObject() &&
396 HeapObject::cast(this)->map()->instance_type() ==
397 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
398}
399
400
401bool Object::IsExternalFloatArray() {
402 return Object::IsHeapObject() &&
403 HeapObject::cast(this)->map()->instance_type() ==
404 EXTERNAL_FLOAT_ARRAY_TYPE;
405}
406
407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000408bool Object::IsFailure() {
409 return HAS_FAILURE_TAG(this);
410}
411
412
413bool Object::IsRetryAfterGC() {
414 return HAS_FAILURE_TAG(this)
415 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
416}
417
418
ager@chromium.org7c537e22008-10-16 08:43:32 +0000419bool Object::IsOutOfMemoryFailure() {
420 return HAS_FAILURE_TAG(this)
421 && Failure::cast(this)->IsOutOfMemoryException();
422}
423
424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425bool Object::IsException() {
426 return this == Failure::Exception();
427}
428
429
430bool Object::IsJSObject() {
431 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000432 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433}
434
435
ager@chromium.org32912102009-01-16 10:38:43 +0000436bool Object::IsJSContextExtensionObject() {
437 return IsHeapObject()
438 && (HeapObject::cast(this)->map()->instance_type() ==
439 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
440}
441
442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000443bool Object::IsMap() {
444 return Object::IsHeapObject()
445 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
446}
447
448
449bool Object::IsFixedArray() {
450 return Object::IsHeapObject()
451 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
452}
453
454
455bool Object::IsDescriptorArray() {
456 return IsFixedArray();
457}
458
459
460bool Object::IsContext() {
461 return Object::IsHeapObject()
462 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000463 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464 HeapObject::cast(this)->map() == Heap::global_context_map());
465}
466
467
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000468bool Object::IsCatchContext() {
469 return Object::IsHeapObject()
470 && HeapObject::cast(this)->map() == Heap::catch_context_map();
471}
472
473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474bool Object::IsGlobalContext() {
475 return Object::IsHeapObject()
476 && HeapObject::cast(this)->map() == Heap::global_context_map();
477}
478
479
480bool Object::IsJSFunction() {
481 return Object::IsHeapObject()
482 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
483}
484
485
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000486template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487 return obj->IsJSFunction();
488}
489
490
491bool Object::IsCode() {
492 return Object::IsHeapObject()
493 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
494}
495
496
497bool Object::IsOddball() {
498 return Object::IsHeapObject()
499 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
500}
501
502
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000503bool Object::IsJSGlobalPropertyCell() {
504 return Object::IsHeapObject()
505 && HeapObject::cast(this)->map()->instance_type()
506 == JS_GLOBAL_PROPERTY_CELL_TYPE;
507}
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510bool Object::IsSharedFunctionInfo() {
511 return Object::IsHeapObject() &&
512 (HeapObject::cast(this)->map()->instance_type() ==
513 SHARED_FUNCTION_INFO_TYPE);
514}
515
516
517bool Object::IsJSValue() {
518 return Object::IsHeapObject()
519 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
520}
521
522
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000523bool Object::IsStringWrapper() {
524 return IsJSValue() && JSValue::cast(this)->value()->IsString();
525}
526
527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528bool Object::IsProxy() {
529 return Object::IsHeapObject()
530 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
531}
532
533
534bool Object::IsBoolean() {
535 return IsTrue() || IsFalse();
536}
537
538
539bool Object::IsJSArray() {
540 return Object::IsHeapObject()
541 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
542}
543
544
ager@chromium.org236ad962008-09-25 09:45:57 +0000545bool Object::IsJSRegExp() {
546 return Object::IsHeapObject()
547 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
548}
549
550
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000551template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552 return obj->IsJSArray();
553}
554
555
556bool Object::IsHashTable() {
557 return Object::IsHeapObject()
558 && HeapObject::cast(this)->map() == Heap::hash_table_map();
559}
560
561
562bool Object::IsDictionary() {
563 return IsHashTable() && this != Heap::symbol_table();
564}
565
566
567bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000568 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000569}
570
571
ager@chromium.orgac091b72010-05-05 07:34:42 +0000572bool Object::IsJSFunctionResultCache() {
573 if (!IsFixedArray()) return false;
574 FixedArray* self = FixedArray::cast(this);
575 int length = self->length();
576 if (length < JSFunctionResultCache::kEntriesIndex) return false;
577 if ((length - JSFunctionResultCache::kEntriesIndex)
578 % JSFunctionResultCache::kEntrySize != 0) {
579 return false;
580 }
581#ifdef DEBUG
582 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
583#endif
584 return true;
585}
586
587
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000588bool Object::IsCompilationCacheTable() {
589 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000590}
591
592
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000593bool Object::IsCodeCacheHashTable() {
594 return IsHashTable();
595}
596
597
ager@chromium.org236ad962008-09-25 09:45:57 +0000598bool Object::IsMapCache() {
599 return IsHashTable();
600}
601
602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603bool Object::IsPrimitive() {
604 return IsOddball() || IsNumber() || IsString();
605}
606
607
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000608bool Object::IsJSGlobalProxy() {
609 bool result = IsHeapObject() &&
610 (HeapObject::cast(this)->map()->instance_type() ==
611 JS_GLOBAL_PROXY_TYPE);
612 ASSERT(!result || IsAccessCheckNeeded());
613 return result;
614}
615
616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000618 if (!IsHeapObject()) return false;
619
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000620 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000621 return type == JS_GLOBAL_OBJECT_TYPE ||
622 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
626bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627 return IsHeapObject() &&
628 (HeapObject::cast(this)->map()->instance_type() ==
629 JS_GLOBAL_OBJECT_TYPE);
630}
631
632
633bool Object::IsJSBuiltinsObject() {
634 return IsHeapObject() &&
635 (HeapObject::cast(this)->map()->instance_type() ==
636 JS_BUILTINS_OBJECT_TYPE);
637}
638
639
640bool Object::IsUndetectableObject() {
641 return IsHeapObject()
642 && HeapObject::cast(this)->map()->is_undetectable();
643}
644
645
646bool Object::IsAccessCheckNeeded() {
647 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000648 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649}
650
651
652bool Object::IsStruct() {
653 if (!IsHeapObject()) return false;
654 switch (HeapObject::cast(this)->map()->instance_type()) {
655#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
656 STRUCT_LIST(MAKE_STRUCT_CASE)
657#undef MAKE_STRUCT_CASE
658 default: return false;
659 }
660}
661
662
663#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
664 bool Object::Is##Name() { \
665 return Object::IsHeapObject() \
666 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
667 }
668 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
669#undef MAKE_STRUCT_PREDICATE
670
671
672bool Object::IsUndefined() {
673 return this == Heap::undefined_value();
674}
675
676
677bool Object::IsTheHole() {
678 return this == Heap::the_hole_value();
679}
680
681
682bool Object::IsNull() {
683 return this == Heap::null_value();
684}
685
686
687bool Object::IsTrue() {
688 return this == Heap::true_value();
689}
690
691
692bool Object::IsFalse() {
693 return this == Heap::false_value();
694}
695
696
697double Object::Number() {
698 ASSERT(IsNumber());
699 return IsSmi()
700 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
701 : reinterpret_cast<HeapNumber*>(this)->value();
702}
703
704
705
706Object* Object::ToSmi() {
707 if (IsSmi()) return this;
708 if (IsHeapNumber()) {
709 double value = HeapNumber::cast(this)->value();
710 int int_value = FastD2I(value);
711 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
712 return Smi::FromInt(int_value);
713 }
714 }
715 return Failure::Exception();
716}
717
718
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000719bool Object::HasSpecificClassOf(String* name) {
720 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
721}
722
723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724Object* Object::GetElement(uint32_t index) {
725 return GetElementWithReceiver(this, index);
726}
727
728
729Object* Object::GetProperty(String* key) {
730 PropertyAttributes attributes;
731 return GetPropertyWithReceiver(this, key, &attributes);
732}
733
734
735Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
736 return GetPropertyWithReceiver(this, key, attributes);
737}
738
739
740#define FIELD_ADDR(p, offset) \
741 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
742
743#define READ_FIELD(p, offset) \
744 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
745
746#define WRITE_FIELD(p, offset, value) \
747 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
748
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000749
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750#define WRITE_BARRIER(object, offset) \
751 Heap::RecordWrite(object->address(), offset);
752
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000753// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000754// write due to the assert validating the written value.
755#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
756 if (mode == UPDATE_WRITE_BARRIER) { \
757 Heap::RecordWrite(object->address(), offset); \
758 } else { \
759 ASSERT(mode == SKIP_WRITE_BARRIER); \
760 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000761 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
762 Page::IsRSetSet(object->address(), offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000763 }
764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765#define READ_DOUBLE_FIELD(p, offset) \
766 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
767
768#define WRITE_DOUBLE_FIELD(p, offset, value) \
769 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
770
771#define READ_INT_FIELD(p, offset) \
772 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
773
774#define WRITE_INT_FIELD(p, offset, value) \
775 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
776
ager@chromium.org3e875802009-06-29 08:26:34 +0000777#define READ_INTPTR_FIELD(p, offset) \
778 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
779
780#define WRITE_INTPTR_FIELD(p, offset, value) \
781 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
782
ager@chromium.org7c537e22008-10-16 08:43:32 +0000783#define READ_UINT32_FIELD(p, offset) \
784 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
785
786#define WRITE_UINT32_FIELD(p, offset, value) \
787 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789#define READ_SHORT_FIELD(p, offset) \
790 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
791
792#define WRITE_SHORT_FIELD(p, offset, value) \
793 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
794
795#define READ_BYTE_FIELD(p, offset) \
796 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
797
798#define WRITE_BYTE_FIELD(p, offset, value) \
799 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
800
801
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000802Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
803 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806
807int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000808 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
812Smi* Smi::FromInt(int value) {
813 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000814 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000815 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000816 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000817 return reinterpret_cast<Smi*>(tagged_value);
818}
819
820
821Smi* Smi::FromIntptr(intptr_t value) {
822 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000823 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
824 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825}
826
827
828Failure::Type Failure::type() const {
829 return static_cast<Type>(value() & kFailureTypeTagMask);
830}
831
832
833bool Failure::IsInternalError() const {
834 return type() == INTERNAL_ERROR;
835}
836
837
838bool Failure::IsOutOfMemoryException() const {
839 return type() == OUT_OF_MEMORY_EXCEPTION;
840}
841
842
843int Failure::requested() const {
844 const int kShiftBits =
845 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
846 STATIC_ASSERT(kShiftBits >= 0);
847 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000848 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000849}
850
851
852AllocationSpace Failure::allocation_space() const {
853 ASSERT_EQ(RETRY_AFTER_GC, type());
854 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
855 & kSpaceTagMask);
856}
857
858
859Failure* Failure::InternalError() {
860 return Construct(INTERNAL_ERROR);
861}
862
863
864Failure* Failure::Exception() {
865 return Construct(EXCEPTION);
866}
867
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000869Failure* Failure::OutOfMemoryException() {
870 return Construct(OUT_OF_MEMORY_EXCEPTION);
871}
872
873
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000875 return static_cast<intptr_t>(
876 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877}
878
879
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000880Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000881 // Assert that the space encoding fits in the three bytes allotted for it.
882 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000883 uintptr_t requested =
884 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
885 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000886 if (((requested << tag_bits) >> tag_bits) != requested) {
887 // No room for entire requested size in the bits. Round down to
888 // maximally representable size.
889 requested = static_cast<intptr_t>(
890 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
891 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000892 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000893 return Construct(RETRY_AFTER_GC, value);
894}
895
896
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000897Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000898 uintptr_t info =
899 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000900 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000901 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902}
903
904
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000905bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906#ifdef DEBUG
907 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
908#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000909
910#ifdef V8_TARGET_ARCH_X64
911 // To be representable as a long smi, the value must be a 32-bit integer.
912 bool result = (value == static_cast<int32_t>(value));
913#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000914 // To be representable as an tagged small integer, the two
915 // most-significant bits of 'value' must be either 00 or 11 due to
916 // sign-extension. To check this we add 01 to the two
917 // most-significant bits, and check if the most-significant bit is 0
918 //
919 // CAUTION: The original code below:
920 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
921 // may lead to incorrect results according to the C language spec, and
922 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
923 // compiler may produce undefined results in case of signed integer
924 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000925 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000926#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000927 ASSERT(result == in_range);
928 return result;
929}
930
931
kasper.lund7276f142008-07-30 08:49:36 +0000932MapWord MapWord::FromMap(Map* map) {
933 return MapWord(reinterpret_cast<uintptr_t>(map));
934}
935
936
937Map* MapWord::ToMap() {
938 return reinterpret_cast<Map*>(value_);
939}
940
941
942bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000943 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000944}
945
946
947MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000948 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
949 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000950}
951
952
953HeapObject* MapWord::ToForwardingAddress() {
954 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000955 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000956}
957
958
959bool MapWord::IsMarked() {
960 return (value_ & kMarkingMask) == 0;
961}
962
963
964void MapWord::SetMark() {
965 value_ &= ~kMarkingMask;
966}
967
968
969void MapWord::ClearMark() {
970 value_ |= kMarkingMask;
971}
972
973
974bool MapWord::IsOverflowed() {
975 return (value_ & kOverflowMask) != 0;
976}
977
978
979void MapWord::SetOverflow() {
980 value_ |= kOverflowMask;
981}
982
983
984void MapWord::ClearOverflow() {
985 value_ &= ~kOverflowMask;
986}
987
988
989MapWord MapWord::EncodeAddress(Address map_address, int offset) {
990 // Offset is the distance in live bytes from the first live object in the
991 // same page. The offset between two objects in the same page should not
992 // exceed the object area size of a page.
993 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
994
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000995 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000996 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
997
998 Page* map_page = Page::FromAddress(map_address);
999 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1000
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001001 uintptr_t map_page_offset =
1002 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001003
1004 uintptr_t encoding =
1005 (compact_offset << kForwardingOffsetShift) |
1006 (map_page_offset << kMapPageOffsetShift) |
1007 (map_page->mc_page_index << kMapPageIndexShift);
1008 return MapWord(encoding);
1009}
1010
1011
1012Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001013 int map_page_index =
1014 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001015 ASSERT_MAP_PAGE_INDEX(map_page_index);
1016
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001017 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001018 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1019 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001020
1021 return (map_space->PageAddress(map_page_index) + map_page_offset);
1022}
1023
1024
1025int MapWord::DecodeOffset() {
1026 // The offset field is represented in the kForwardingOffsetBits
1027 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001028 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1029 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1030 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001031}
1032
1033
1034MapWord MapWord::FromEncodedAddress(Address address) {
1035 return MapWord(reinterpret_cast<uintptr_t>(address));
1036}
1037
1038
1039Address MapWord::ToEncodedAddress() {
1040 return reinterpret_cast<Address>(value_);
1041}
1042
1043
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044#ifdef DEBUG
1045void HeapObject::VerifyObjectField(int offset) {
1046 VerifyPointer(READ_FIELD(this, offset));
1047}
1048#endif
1049
1050
1051Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001052 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053}
1054
1055
1056void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001057 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058}
1059
1060
kasper.lund7276f142008-07-30 08:49:36 +00001061MapWord HeapObject::map_word() {
1062 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1063}
1064
1065
1066void HeapObject::set_map_word(MapWord map_word) {
1067 // WRITE_FIELD does not update the remembered set, but there is no need
1068 // here.
1069 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1070}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001071
1072
1073HeapObject* HeapObject::FromAddress(Address address) {
1074 ASSERT_TAG_ALIGNED(address);
1075 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1076}
1077
1078
1079Address HeapObject::address() {
1080 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1081}
1082
1083
1084int HeapObject::Size() {
1085 return SizeFromMap(map());
1086}
1087
1088
1089void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1090 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1091 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1092}
1093
1094
1095void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1096 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1097}
1098
1099
kasper.lund7276f142008-07-30 08:49:36 +00001100bool HeapObject::IsMarked() {
1101 return map_word().IsMarked();
1102}
1103
1104
1105void HeapObject::SetMark() {
1106 ASSERT(!IsMarked());
1107 MapWord first_word = map_word();
1108 first_word.SetMark();
1109 set_map_word(first_word);
1110}
1111
1112
1113void HeapObject::ClearMark() {
1114 ASSERT(IsMarked());
1115 MapWord first_word = map_word();
1116 first_word.ClearMark();
1117 set_map_word(first_word);
1118}
1119
1120
1121bool HeapObject::IsOverflowed() {
1122 return map_word().IsOverflowed();
1123}
1124
1125
1126void HeapObject::SetOverflow() {
1127 MapWord first_word = map_word();
1128 first_word.SetOverflow();
1129 set_map_word(first_word);
1130}
1131
1132
1133void HeapObject::ClearOverflow() {
1134 ASSERT(IsOverflowed());
1135 MapWord first_word = map_word();
1136 first_word.ClearOverflow();
1137 set_map_word(first_word);
1138}
1139
1140
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001141double HeapNumber::value() {
1142 return READ_DOUBLE_FIELD(this, kValueOffset);
1143}
1144
1145
1146void HeapNumber::set_value(double value) {
1147 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1148}
1149
1150
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001151int HeapNumber::get_exponent() {
1152 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1153 kExponentShift) - kExponentBias;
1154}
1155
1156
1157int HeapNumber::get_sign() {
1158 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001163
1164
1165Array* JSObject::elements() {
1166 Object* array = READ_FIELD(this, kElementsOffset);
1167 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001168 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1169 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001170 return reinterpret_cast<Array*>(array);
1171}
1172
1173
1174void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1175 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001176 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1177 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001178 WRITE_FIELD(this, kElementsOffset, value);
1179 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1180}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181
1182
1183void JSObject::initialize_properties() {
1184 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1185 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1186}
1187
1188
1189void JSObject::initialize_elements() {
1190 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1191 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1192}
1193
1194
1195ACCESSORS(Oddball, to_string, String, kToStringOffset)
1196ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1197
1198
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001199Object* JSGlobalPropertyCell::value() {
1200 return READ_FIELD(this, kValueOffset);
1201}
1202
1203
1204void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1205 // The write barrier is not used for global property cells.
1206 ASSERT(!val->IsJSGlobalPropertyCell());
1207 WRITE_FIELD(this, kValueOffset, val);
1208}
1209
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001212 InstanceType type = map()->instance_type();
1213 // Check for the most common kind of JavaScript object before
1214 // falling into the generic switch. This speeds up the internal
1215 // field operations considerably on average.
1216 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1217 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001218 case JS_GLOBAL_PROXY_TYPE:
1219 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220 case JS_GLOBAL_OBJECT_TYPE:
1221 return JSGlobalObject::kSize;
1222 case JS_BUILTINS_OBJECT_TYPE:
1223 return JSBuiltinsObject::kSize;
1224 case JS_FUNCTION_TYPE:
1225 return JSFunction::kSize;
1226 case JS_VALUE_TYPE:
1227 return JSValue::kSize;
1228 case JS_ARRAY_TYPE:
1229 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001230 case JS_REGEXP_TYPE:
1231 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001232 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233 return JSObject::kHeaderSize;
1234 default:
1235 UNREACHABLE();
1236 return 0;
1237 }
1238}
1239
1240
1241int JSObject::GetInternalFieldCount() {
1242 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001243 // Make sure to adjust for the number of in-object properties. These
1244 // properties do contribute to the size, but are not internal fields.
1245 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1246 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001247}
1248
1249
1250Object* JSObject::GetInternalField(int index) {
1251 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001252 // Internal objects do follow immediately after the header, whereas in-object
1253 // properties are at the end of the object. Therefore there is no need
1254 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001255 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1256}
1257
1258
1259void JSObject::SetInternalField(int index, Object* value) {
1260 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001261 // Internal objects do follow immediately after the header, whereas in-object
1262 // properties are at the end of the object. Therefore there is no need
1263 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001264 int offset = GetHeaderSize() + (kPointerSize * index);
1265 WRITE_FIELD(this, offset, value);
1266 WRITE_BARRIER(this, offset);
1267}
1268
1269
ager@chromium.org7c537e22008-10-16 08:43:32 +00001270// Access fast-case object properties at index. The use of these routines
1271// is needed to correctly distinguish between properties stored in-object and
1272// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001273Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001274 // Adjust for the number of properties stored in the object.
1275 index -= map()->inobject_properties();
1276 if (index < 0) {
1277 int offset = map()->instance_size() + (index * kPointerSize);
1278 return READ_FIELD(this, offset);
1279 } else {
1280 ASSERT(index < properties()->length());
1281 return properties()->get(index);
1282 }
1283}
1284
1285
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001286Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001287 // Adjust for the number of properties stored in the object.
1288 index -= map()->inobject_properties();
1289 if (index < 0) {
1290 int offset = map()->instance_size() + (index * kPointerSize);
1291 WRITE_FIELD(this, offset, value);
1292 WRITE_BARRIER(this, offset);
1293 } else {
1294 ASSERT(index < properties()->length());
1295 properties()->set(index, value);
1296 }
1297 return value;
1298}
1299
1300
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001301Object* JSObject::InObjectPropertyAt(int index) {
1302 // Adjust for the number of properties stored in the object.
1303 index -= map()->inobject_properties();
1304 ASSERT(index < 0);
1305 int offset = map()->instance_size() + (index * kPointerSize);
1306 return READ_FIELD(this, offset);
1307}
1308
1309
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001310Object* JSObject::InObjectPropertyAtPut(int index,
1311 Object* value,
1312 WriteBarrierMode mode) {
1313 // Adjust for the number of properties stored in the object.
1314 index -= map()->inobject_properties();
1315 ASSERT(index < 0);
1316 int offset = map()->instance_size() + (index * kPointerSize);
1317 WRITE_FIELD(this, offset, value);
1318 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1319 return value;
1320}
1321
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001325 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001326 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001327 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328 }
1329}
1330
1331
1332void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001333 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001334 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001335 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001336 }
1337}
1338
1339
1340bool JSObject::HasFastProperties() {
1341 return !properties()->IsDictionary();
1342}
1343
1344
1345bool Array::IndexFromObject(Object* object, uint32_t* index) {
1346 if (object->IsSmi()) {
1347 int value = Smi::cast(object)->value();
1348 if (value < 0) return false;
1349 *index = value;
1350 return true;
1351 }
1352 if (object->IsHeapNumber()) {
1353 double value = HeapNumber::cast(object)->value();
1354 uint32_t uint_value = static_cast<uint32_t>(value);
1355 if (value == static_cast<double>(uint_value)) {
1356 *index = uint_value;
1357 return true;
1358 }
1359 }
1360 return false;
1361}
1362
1363
1364bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1365 if (!this->IsJSValue()) return false;
1366
1367 JSValue* js_value = JSValue::cast(this);
1368 if (!js_value->value()->IsString()) return false;
1369
1370 String* str = String::cast(js_value->value());
1371 if (index >= (uint32_t)str->length()) return false;
1372
1373 return true;
1374}
1375
1376
1377Object* FixedArray::get(int index) {
1378 ASSERT(index >= 0 && index < this->length());
1379 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1380}
1381
1382
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001383void FixedArray::set(int index, Smi* value) {
1384 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1385 int offset = kHeaderSize + index * kPointerSize;
1386 WRITE_FIELD(this, offset, value);
1387}
1388
1389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001390void FixedArray::set(int index, Object* value) {
1391 ASSERT(index >= 0 && index < this->length());
1392 int offset = kHeaderSize + index * kPointerSize;
1393 WRITE_FIELD(this, offset, value);
1394 WRITE_BARRIER(this, offset);
1395}
1396
1397
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001398WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001399 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1400 return UPDATE_WRITE_BARRIER;
1401}
1402
1403
1404void FixedArray::set(int index,
1405 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001406 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 ASSERT(index >= 0 && index < this->length());
1408 int offset = kHeaderSize + index * kPointerSize;
1409 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001410 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411}
1412
1413
1414void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1415 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001416 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1418}
1419
1420
1421void FixedArray::set_undefined(int index) {
1422 ASSERT(index >= 0 && index < this->length());
1423 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1424 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1425 Heap::undefined_value());
1426}
1427
1428
ager@chromium.org236ad962008-09-25 09:45:57 +00001429void FixedArray::set_null(int index) {
1430 ASSERT(index >= 0 && index < this->length());
1431 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1432 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1433}
1434
1435
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436void FixedArray::set_the_hole(int index) {
1437 ASSERT(index >= 0 && index < this->length());
1438 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1439 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1440}
1441
1442
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001443Object** FixedArray::data_start() {
1444 return HeapObject::RawField(this, kHeaderSize);
1445}
1446
1447
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001448bool DescriptorArray::IsEmpty() {
1449 ASSERT(this == Heap::empty_descriptor_array() ||
1450 this->length() > 2);
1451 return this == Heap::empty_descriptor_array();
1452}
1453
1454
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1456 Object* tmp = array->get(first);
1457 fast_set(array, first, array->get(second));
1458 fast_set(array, second, tmp);
1459}
1460
1461
1462int DescriptorArray::Search(String* name) {
1463 SLOW_ASSERT(IsSortedNoDuplicates());
1464
1465 // Check for empty descriptor array.
1466 int nof = number_of_descriptors();
1467 if (nof == 0) return kNotFound;
1468
1469 // Fast case: do linear search for small arrays.
1470 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001471 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001472 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 }
1474
1475 // Slow case: perform binary search.
1476 return BinarySearch(name, 0, nof - 1);
1477}
1478
1479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480String* DescriptorArray::GetKey(int descriptor_number) {
1481 ASSERT(descriptor_number < number_of_descriptors());
1482 return String::cast(get(ToKeyIndex(descriptor_number)));
1483}
1484
1485
1486Object* DescriptorArray::GetValue(int descriptor_number) {
1487 ASSERT(descriptor_number < number_of_descriptors());
1488 return GetContentArray()->get(ToValueIndex(descriptor_number));
1489}
1490
1491
1492Smi* DescriptorArray::GetDetails(int descriptor_number) {
1493 ASSERT(descriptor_number < number_of_descriptors());
1494 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1495}
1496
1497
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001498PropertyType DescriptorArray::GetType(int descriptor_number) {
1499 ASSERT(descriptor_number < number_of_descriptors());
1500 return PropertyDetails(GetDetails(descriptor_number)).type();
1501}
1502
1503
1504int DescriptorArray::GetFieldIndex(int descriptor_number) {
1505 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1506}
1507
1508
1509JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1510 return JSFunction::cast(GetValue(descriptor_number));
1511}
1512
1513
1514Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1515 ASSERT(GetType(descriptor_number) == CALLBACKS);
1516 return GetValue(descriptor_number);
1517}
1518
1519
1520AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1521 ASSERT(GetType(descriptor_number) == CALLBACKS);
1522 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1523 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1524}
1525
1526
1527bool DescriptorArray::IsProperty(int descriptor_number) {
1528 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1529}
1530
1531
1532bool DescriptorArray::IsTransition(int descriptor_number) {
1533 PropertyType t = GetType(descriptor_number);
1534 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1535}
1536
1537
1538bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1539 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1540}
1541
1542
1543bool DescriptorArray::IsDontEnum(int descriptor_number) {
1544 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1545}
1546
1547
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1549 desc->Init(GetKey(descriptor_number),
1550 GetValue(descriptor_number),
1551 GetDetails(descriptor_number));
1552}
1553
1554
1555void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1556 // Range check.
1557 ASSERT(descriptor_number < number_of_descriptors());
1558
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001559 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1561 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1562
1563 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1564 FixedArray* content_array = GetContentArray();
1565 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1566 fast_set(content_array, ToDetailsIndex(descriptor_number),
1567 desc->GetDetails().AsSmi());
1568}
1569
1570
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001571void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1572 Descriptor desc;
1573 src->Get(src_index, &desc);
1574 Set(index, &desc);
1575}
1576
1577
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578void DescriptorArray::Swap(int first, int second) {
1579 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1580 FixedArray* content_array = GetContentArray();
1581 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1582 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1583}
1584
1585
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001586bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001587 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001588 if (!max_index_object->IsSmi()) return false;
1589 return 0 !=
1590 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1591}
1592
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001593uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001595 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 if (!max_index_object->IsSmi()) return 0;
1597 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1598 return value >> kRequiresSlowElementsTagSize;
1599}
1600
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001601void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001602 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001603}
1604
1605
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001606// ------------------------------------
1607// Cast operations
1608
1609
1610CAST_ACCESSOR(FixedArray)
1611CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001613CAST_ACCESSOR(JSFunctionResultCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001614CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001615CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001616CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617CAST_ACCESSOR(String)
1618CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001619CAST_ACCESSOR(SeqAsciiString)
1620CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001621CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622CAST_ACCESSOR(ExternalString)
1623CAST_ACCESSOR(ExternalAsciiString)
1624CAST_ACCESSOR(ExternalTwoByteString)
1625CAST_ACCESSOR(JSObject)
1626CAST_ACCESSOR(Smi)
1627CAST_ACCESSOR(Failure)
1628CAST_ACCESSOR(HeapObject)
1629CAST_ACCESSOR(HeapNumber)
1630CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001631CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632CAST_ACCESSOR(SharedFunctionInfo)
1633CAST_ACCESSOR(Map)
1634CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001635CAST_ACCESSOR(GlobalObject)
1636CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637CAST_ACCESSOR(JSGlobalObject)
1638CAST_ACCESSOR(JSBuiltinsObject)
1639CAST_ACCESSOR(Code)
1640CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001641CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001642CAST_ACCESSOR(Proxy)
1643CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001644CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001645CAST_ACCESSOR(ExternalArray)
1646CAST_ACCESSOR(ExternalByteArray)
1647CAST_ACCESSOR(ExternalUnsignedByteArray)
1648CAST_ACCESSOR(ExternalShortArray)
1649CAST_ACCESSOR(ExternalUnsignedShortArray)
1650CAST_ACCESSOR(ExternalIntArray)
1651CAST_ACCESSOR(ExternalUnsignedIntArray)
1652CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653CAST_ACCESSOR(Struct)
1654
1655
1656#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1657 STRUCT_LIST(MAKE_STRUCT_CAST)
1658#undef MAKE_STRUCT_CAST
1659
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001660
1661template <typename Shape, typename Key>
1662HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001663 ASSERT(obj->IsHashTable());
1664 return reinterpret_cast<HashTable*>(obj);
1665}
1666
1667
1668INT_ACCESSORS(Array, length, kLengthOffset)
1669
1670
ager@chromium.orgac091b72010-05-05 07:34:42 +00001671SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001672
1673
1674uint32_t String::hash_field() {
1675 return READ_UINT32_FIELD(this, kHashFieldOffset);
1676}
1677
1678
1679void String::set_hash_field(uint32_t value) {
1680 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1681}
1682
1683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001684bool String::Equals(String* other) {
1685 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001686 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1687 return false;
1688 }
1689 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690}
1691
1692
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001693Object* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001694 if (!StringShape(this).IsCons()) return this;
1695 ConsString* cons = ConsString::cast(this);
1696 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001697 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698}
1699
1700
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001701String* String::TryFlattenGetString(PretenureFlag pretenure) {
1702 Object* flat = TryFlatten(pretenure);
1703 return flat->IsFailure() ? this : String::cast(flat);
1704}
1705
1706
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001707uint16_t String::Get(int index) {
1708 ASSERT(index >= 0 && index < length());
1709 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001710 case kSeqStringTag | kAsciiStringTag:
1711 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1712 case kSeqStringTag | kTwoByteStringTag:
1713 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1714 case kConsStringTag | kAsciiStringTag:
1715 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001716 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001717 case kExternalStringTag | kAsciiStringTag:
1718 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1719 case kExternalStringTag | kTwoByteStringTag:
1720 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001721 default:
1722 break;
1723 }
1724
1725 UNREACHABLE();
1726 return 0;
1727}
1728
1729
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001730void String::Set(int index, uint16_t value) {
1731 ASSERT(index >= 0 && index < length());
1732 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733
ager@chromium.org5ec48922009-05-05 07:25:34 +00001734 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001735 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1736 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737}
1738
1739
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001740bool String::IsFlat() {
1741 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001742 case kConsStringTag: {
1743 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001744 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001745 return second->length() == 0;
1746 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001747 default:
1748 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749 }
1750}
1751
1752
ager@chromium.org7c537e22008-10-16 08:43:32 +00001753uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 ASSERT(index >= 0 && index < length());
1755 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1756}
1757
1758
ager@chromium.org7c537e22008-10-16 08:43:32 +00001759void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1761 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1762 static_cast<byte>(value));
1763}
1764
1765
ager@chromium.org7c537e22008-10-16 08:43:32 +00001766Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001767 return FIELD_ADDR(this, kHeaderSize);
1768}
1769
1770
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001771char* SeqAsciiString::GetChars() {
1772 return reinterpret_cast<char*>(GetCharsAddress());
1773}
1774
1775
ager@chromium.org7c537e22008-10-16 08:43:32 +00001776Address SeqTwoByteString::GetCharsAddress() {
1777 return FIELD_ADDR(this, kHeaderSize);
1778}
1779
1780
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001781uc16* SeqTwoByteString::GetChars() {
1782 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1783}
1784
1785
ager@chromium.org7c537e22008-10-16 08:43:32 +00001786uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 ASSERT(index >= 0 && index < length());
1788 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1789}
1790
1791
ager@chromium.org7c537e22008-10-16 08:43:32 +00001792void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 ASSERT(index >= 0 && index < length());
1794 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1795}
1796
1797
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001798int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001799 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800}
1801
1802
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001803int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001804 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805}
1806
1807
ager@chromium.org870a0b62008-11-04 11:43:05 +00001808String* ConsString::first() {
1809 return String::cast(READ_FIELD(this, kFirstOffset));
1810}
1811
1812
1813Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 return READ_FIELD(this, kFirstOffset);
1815}
1816
1817
ager@chromium.org870a0b62008-11-04 11:43:05 +00001818void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001819 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001820 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001821}
1822
1823
ager@chromium.org870a0b62008-11-04 11:43:05 +00001824String* ConsString::second() {
1825 return String::cast(READ_FIELD(this, kSecondOffset));
1826}
1827
1828
1829Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 return READ_FIELD(this, kSecondOffset);
1831}
1832
1833
ager@chromium.org870a0b62008-11-04 11:43:05 +00001834void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001836 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837}
1838
1839
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001840ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1841 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1842}
1843
1844
1845void ExternalAsciiString::set_resource(
1846 ExternalAsciiString::Resource* resource) {
1847 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1848}
1849
1850
1851ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1852 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1853}
1854
1855
1856void ExternalTwoByteString::set_resource(
1857 ExternalTwoByteString::Resource* resource) {
1858 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1859}
1860
1861
ager@chromium.orgac091b72010-05-05 07:34:42 +00001862void JSFunctionResultCache::MakeZeroSize() {
1863 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1864 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1865}
1866
1867
1868void JSFunctionResultCache::Clear() {
1869 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1870 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
1871 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1872 MakeZeroSize();
1873}
1874
1875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876byte ByteArray::get(int index) {
1877 ASSERT(index >= 0 && index < this->length());
1878 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1879}
1880
1881
1882void ByteArray::set(int index, byte value) {
1883 ASSERT(index >= 0 && index < this->length());
1884 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1885}
1886
1887
1888int ByteArray::get_int(int index) {
1889 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1890 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1891}
1892
1893
1894ByteArray* ByteArray::FromDataStartAddress(Address address) {
1895 ASSERT_TAG_ALIGNED(address);
1896 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1897}
1898
1899
1900Address ByteArray::GetDataStartAddress() {
1901 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1902}
1903
1904
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001905uint8_t* PixelArray::external_pointer() {
1906 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1907 return reinterpret_cast<uint8_t*>(ptr);
1908}
1909
1910
1911void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1912 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1913 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1914}
1915
1916
1917uint8_t PixelArray::get(int index) {
1918 ASSERT((index >= 0) && (index < this->length()));
1919 uint8_t* ptr = external_pointer();
1920 return ptr[index];
1921}
1922
1923
1924void PixelArray::set(int index, uint8_t value) {
1925 ASSERT((index >= 0) && (index < this->length()));
1926 uint8_t* ptr = external_pointer();
1927 ptr[index] = value;
1928}
1929
1930
ager@chromium.org3811b432009-10-28 14:53:37 +00001931void* ExternalArray::external_pointer() {
1932 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1933 return reinterpret_cast<void*>(ptr);
1934}
1935
1936
1937void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1938 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1939 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1940}
1941
1942
1943int8_t ExternalByteArray::get(int index) {
1944 ASSERT((index >= 0) && (index < this->length()));
1945 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1946 return ptr[index];
1947}
1948
1949
1950void ExternalByteArray::set(int index, int8_t value) {
1951 ASSERT((index >= 0) && (index < this->length()));
1952 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1953 ptr[index] = value;
1954}
1955
1956
1957uint8_t ExternalUnsignedByteArray::get(int index) {
1958 ASSERT((index >= 0) && (index < this->length()));
1959 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1960 return ptr[index];
1961}
1962
1963
1964void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1965 ASSERT((index >= 0) && (index < this->length()));
1966 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1967 ptr[index] = value;
1968}
1969
1970
1971int16_t ExternalShortArray::get(int index) {
1972 ASSERT((index >= 0) && (index < this->length()));
1973 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1974 return ptr[index];
1975}
1976
1977
1978void ExternalShortArray::set(int index, int16_t value) {
1979 ASSERT((index >= 0) && (index < this->length()));
1980 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1981 ptr[index] = value;
1982}
1983
1984
1985uint16_t ExternalUnsignedShortArray::get(int index) {
1986 ASSERT((index >= 0) && (index < this->length()));
1987 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1988 return ptr[index];
1989}
1990
1991
1992void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1993 ASSERT((index >= 0) && (index < this->length()));
1994 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1995 ptr[index] = value;
1996}
1997
1998
1999int32_t ExternalIntArray::get(int index) {
2000 ASSERT((index >= 0) && (index < this->length()));
2001 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2002 return ptr[index];
2003}
2004
2005
2006void ExternalIntArray::set(int index, int32_t value) {
2007 ASSERT((index >= 0) && (index < this->length()));
2008 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2009 ptr[index] = value;
2010}
2011
2012
2013uint32_t ExternalUnsignedIntArray::get(int index) {
2014 ASSERT((index >= 0) && (index < this->length()));
2015 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2016 return ptr[index];
2017}
2018
2019
2020void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2021 ASSERT((index >= 0) && (index < this->length()));
2022 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2023 ptr[index] = value;
2024}
2025
2026
2027float ExternalFloatArray::get(int index) {
2028 ASSERT((index >= 0) && (index < this->length()));
2029 float* ptr = static_cast<float*>(external_pointer());
2030 return ptr[index];
2031}
2032
2033
2034void ExternalFloatArray::set(int index, float value) {
2035 ASSERT((index >= 0) && (index < this->length()));
2036 float* ptr = static_cast<float*>(external_pointer());
2037 ptr[index] = value;
2038}
2039
2040
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002041int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002042 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2043}
2044
2045
2046int Map::inobject_properties() {
2047 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048}
2049
2050
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002051int Map::pre_allocated_property_fields() {
2052 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2053}
2054
2055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002056int HeapObject::SizeFromMap(Map* map) {
2057 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002058 // Only inline the most frequent cases.
2059 if (instance_type == JS_OBJECT_TYPE ||
2060 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2061 (kStringTag | kConsStringTag) ||
2062 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 if (instance_type == FIXED_ARRAY_TYPE) {
2064 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2065 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002066 if (instance_type == BYTE_ARRAY_TYPE) {
2067 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2068 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069 // Otherwise do the general size computation.
2070 return SlowSizeFromMap(map);
2071}
2072
2073
2074void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002075 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002076 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077 ASSERT(0 <= value && value < 256);
2078 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2079}
2080
2081
ager@chromium.org7c537e22008-10-16 08:43:32 +00002082void Map::set_inobject_properties(int value) {
2083 ASSERT(0 <= value && value < 256);
2084 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2085}
2086
2087
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002088void Map::set_pre_allocated_property_fields(int value) {
2089 ASSERT(0 <= value && value < 256);
2090 WRITE_BYTE_FIELD(this,
2091 kPreAllocatedPropertyFieldsOffset,
2092 static_cast<byte>(value));
2093}
2094
2095
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096InstanceType Map::instance_type() {
2097 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2098}
2099
2100
2101void Map::set_instance_type(InstanceType value) {
2102 ASSERT(0 <= value && value < 256);
2103 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2104}
2105
2106
2107int Map::unused_property_fields() {
2108 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2109}
2110
2111
2112void Map::set_unused_property_fields(int value) {
2113 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2114}
2115
2116
2117byte Map::bit_field() {
2118 return READ_BYTE_FIELD(this, kBitFieldOffset);
2119}
2120
2121
2122void Map::set_bit_field(byte value) {
2123 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2124}
2125
2126
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002127byte Map::bit_field2() {
2128 return READ_BYTE_FIELD(this, kBitField2Offset);
2129}
2130
2131
2132void Map::set_bit_field2(byte value) {
2133 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2134}
2135
2136
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137void Map::set_non_instance_prototype(bool value) {
2138 if (value) {
2139 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2140 } else {
2141 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2142 }
2143}
2144
2145
2146bool Map::has_non_instance_prototype() {
2147 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2148}
2149
2150
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002151void Map::set_function_with_prototype(bool value) {
2152 if (value) {
2153 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2154 } else {
2155 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2156 }
2157}
2158
2159
2160bool Map::function_with_prototype() {
2161 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2162}
2163
2164
ager@chromium.org870a0b62008-11-04 11:43:05 +00002165void Map::set_is_access_check_needed(bool access_check_needed) {
2166 if (access_check_needed) {
2167 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2168 } else {
2169 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2170 }
2171}
2172
2173
2174bool Map::is_access_check_needed() {
2175 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2176}
2177
2178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179Code::Flags Code::flags() {
2180 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2181}
2182
2183
2184void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002185 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186 // Make sure that all call stubs have an arguments count.
2187 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2188 ExtractArgumentsCountFromFlags(flags) >= 0);
2189 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2190}
2191
2192
2193Code::Kind Code::kind() {
2194 return ExtractKindFromFlags(flags());
2195}
2196
2197
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002198InLoopFlag Code::ic_in_loop() {
2199 return ExtractICInLoopFromFlags(flags());
2200}
2201
2202
kasper.lund7276f142008-07-30 08:49:36 +00002203InlineCacheState Code::ic_state() {
2204 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002205 // Only allow uninitialized or debugger states for non-IC code
2206 // objects. This is used in the debugger to determine whether or not
2207 // a call to code object has been replaced with a debug break call.
2208 ASSERT(is_inline_cache_stub() ||
2209 result == UNINITIALIZED ||
2210 result == DEBUG_BREAK ||
2211 result == DEBUG_PREPARE_STEP_IN);
2212 return result;
2213}
2214
2215
2216PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002217 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218 return ExtractTypeFromFlags(flags());
2219}
2220
2221
2222int Code::arguments_count() {
2223 ASSERT(is_call_stub() || kind() == STUB);
2224 return ExtractArgumentsCountFromFlags(flags());
2225}
2226
2227
2228CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002229 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002230 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2231 kStubMajorKeyOffset));
2232}
2233
2234
2235void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002236 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002237 ASSERT(0 <= major && major < 256);
2238 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239}
2240
2241
2242bool Code::is_inline_cache_stub() {
2243 Kind kind = this->kind();
2244 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2245}
2246
2247
2248Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002249 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002250 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251 PropertyType type,
2252 int argc) {
2253 // Compute the bit mask.
2254 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002255 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002256 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 bits |= type << kFlagsTypeShift;
2258 bits |= argc << kFlagsArgumentsCountShift;
2259 // Cast to flags and validate result before returning it.
2260 Flags result = static_cast<Flags>(bits);
2261 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002262 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002263 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264 ASSERT(ExtractTypeFromFlags(result) == type);
2265 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2266 return result;
2267}
2268
2269
2270Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2271 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002272 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002274 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275}
2276
2277
2278Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2279 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2280 return static_cast<Kind>(bits);
2281}
2282
2283
kasper.lund7276f142008-07-30 08:49:36 +00002284InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2285 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 return static_cast<InlineCacheState>(bits);
2287}
2288
2289
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002290InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2291 int bits = (flags & kFlagsICInLoopMask);
2292 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2293}
2294
2295
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002296PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2297 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2298 return static_cast<PropertyType>(bits);
2299}
2300
2301
2302int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2303 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2304}
2305
2306
2307Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2308 int bits = flags & ~kFlagsTypeMask;
2309 return static_cast<Flags>(bits);
2310}
2311
2312
ager@chromium.org8bb60582008-12-11 12:02:20 +00002313Code* Code::GetCodeFromTargetAddress(Address address) {
2314 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2315 // GetCodeFromTargetAddress might be called when marking objects during mark
2316 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2317 // Code::cast. Code::cast does not work when the object's map is
2318 // marked.
2319 Code* result = reinterpret_cast<Code*>(code);
2320 return result;
2321}
2322
2323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324Object* Map::prototype() {
2325 return READ_FIELD(this, kPrototypeOffset);
2326}
2327
2328
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002329void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330 ASSERT(value->IsNull() || value->IsJSObject());
2331 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002332 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333}
2334
2335
2336ACCESSORS(Map, instance_descriptors, DescriptorArray,
2337 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002338ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339ACCESSORS(Map, constructor, Object, kConstructorOffset)
2340
2341ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2342ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2343
2344ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2345ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002346ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002348ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002349
2350ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2351ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2352ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2353ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2354ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002355ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002356
2357ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2358ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2359ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2360
2361ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2362ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2363ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2364ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2365ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2366ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2367
2368ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2369ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2370
2371ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2372ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2373
2374ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2375ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2377 kPropertyAccessorsOffset)
2378ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2379 kPrototypeTemplateOffset)
2380ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2381ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2382 kNamedPropertyHandlerOffset)
2383ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2384 kIndexedPropertyHandlerOffset)
2385ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2386 kInstanceTemplateOffset)
2387ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2388ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2390 kInstanceCallHandlerOffset)
2391ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2392 kAccessCheckInfoOffset)
2393ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2394
2395ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002396ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2397 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398
2399ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2400ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2401
2402ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2403
2404ACCESSORS(Script, source, Object, kSourceOffset)
2405ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002406ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2408ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002409ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002410ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2412ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002413ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002414ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002415ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002416ACCESSORS(Script, eval_from_instructions_offset, Smi,
2417 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002418
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002419#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2421ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2422ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2423ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2424
2425ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2426ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2427ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2428ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002429#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430
2431ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002432ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2434 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002435ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2437ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002438ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002439ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2440 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441
2442BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2443 kHiddenPrototypeBit)
2444BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2445BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2446 kNeedsAccessCheckBit)
2447BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2448 kIsExpressionBit)
2449BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2450 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002451BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002452 has_only_simple_this_property_assignments,
2453 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002454BOOL_ACCESSORS(SharedFunctionInfo,
2455 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002456 try_full_codegen,
2457 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002458
2459INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2460INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2461 kFormalParameterCountOffset)
2462INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2463 kExpectedNofPropertiesOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002464INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2466 kStartPositionAndTypeOffset)
2467INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2468INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2469 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002470INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2471 kCompilerHintsOffset)
2472INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2473 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474
2475
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002476ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2477ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2478
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002479bool Script::HasValidSource() {
2480 Object* src = this->source();
2481 if (!src->IsString()) return true;
2482 String* src_str = String::cast(src);
2483 if (!StringShape(src_str).IsExternal()) return true;
2484 if (src_str->IsAsciiRepresentation()) {
2485 return ExternalAsciiString::cast(src)->resource() != NULL;
2486 } else if (src_str->IsTwoByteRepresentation()) {
2487 return ExternalTwoByteString::cast(src)->resource() != NULL;
2488 }
2489 return true;
2490}
2491
2492
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002493void SharedFunctionInfo::DontAdaptArguments() {
2494 ASSERT(code()->kind() == Code::BUILTIN);
2495 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2496}
2497
2498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002499int SharedFunctionInfo::start_position() {
2500 return start_position_and_type() >> kStartPositionShift;
2501}
2502
2503
2504void SharedFunctionInfo::set_start_position(int start_position) {
2505 set_start_position_and_type((start_position << kStartPositionShift)
2506 | (start_position_and_type() & ~kStartPositionMask));
2507}
2508
2509
2510Code* SharedFunctionInfo::code() {
2511 return Code::cast(READ_FIELD(this, kCodeOffset));
2512}
2513
2514
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002515void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002517 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002518}
2519
2520
2521bool SharedFunctionInfo::is_compiled() {
2522 // TODO(1242782): Create a code kind for uncompiled code.
2523 return code()->kind() != Code::STUB;
2524}
2525
2526
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002527bool SharedFunctionInfo::IsApiFunction() {
2528 return function_data()->IsFunctionTemplateInfo();
2529}
2530
2531
2532FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2533 ASSERT(IsApiFunction());
2534 return FunctionTemplateInfo::cast(function_data());
2535}
2536
2537
2538bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002539 return function_data()->IsSmi();
2540}
2541
2542
2543int SharedFunctionInfo::custom_call_generator_id() {
2544 ASSERT(HasCustomCallGenerator());
2545 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002546}
2547
2548
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002549bool JSFunction::IsBuiltin() {
2550 return context()->global()->IsJSBuiltinsObject();
2551}
2552
2553
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002554Code* JSFunction::code() {
2555 return shared()->code();
2556}
2557
2558
2559void JSFunction::set_code(Code* value) {
2560 shared()->set_code(value);
2561}
2562
2563
2564Context* JSFunction::context() {
2565 return Context::cast(READ_FIELD(this, kContextOffset));
2566}
2567
2568
2569Object* JSFunction::unchecked_context() {
2570 return READ_FIELD(this, kContextOffset);
2571}
2572
2573
2574void JSFunction::set_context(Object* value) {
2575 ASSERT(value == Heap::undefined_value() || value->IsContext());
2576 WRITE_FIELD(this, kContextOffset, value);
2577 WRITE_BARRIER(this, kContextOffset);
2578}
2579
2580ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2581 kPrototypeOrInitialMapOffset)
2582
2583
2584Map* JSFunction::initial_map() {
2585 return Map::cast(prototype_or_initial_map());
2586}
2587
2588
2589void JSFunction::set_initial_map(Map* value) {
2590 set_prototype_or_initial_map(value);
2591}
2592
2593
2594bool JSFunction::has_initial_map() {
2595 return prototype_or_initial_map()->IsMap();
2596}
2597
2598
2599bool JSFunction::has_instance_prototype() {
2600 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2601}
2602
2603
2604bool JSFunction::has_prototype() {
2605 return map()->has_non_instance_prototype() || has_instance_prototype();
2606}
2607
2608
2609Object* JSFunction::instance_prototype() {
2610 ASSERT(has_instance_prototype());
2611 if (has_initial_map()) return initial_map()->prototype();
2612 // When there is no initial map and the prototype is a JSObject, the
2613 // initial map field is used for the prototype field.
2614 return prototype_or_initial_map();
2615}
2616
2617
2618Object* JSFunction::prototype() {
2619 ASSERT(has_prototype());
2620 // If the function's prototype property has been set to a non-JSObject
2621 // value, that value is stored in the constructor field of the map.
2622 if (map()->has_non_instance_prototype()) return map()->constructor();
2623 return instance_prototype();
2624}
2625
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002626bool JSFunction::should_have_prototype() {
2627 return map()->function_with_prototype();
2628}
2629
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630
2631bool JSFunction::is_compiled() {
2632 return shared()->is_compiled();
2633}
2634
2635
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002636int JSFunction::NumberOfLiterals() {
2637 return literals()->length();
2638}
2639
2640
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2642 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002643 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002644}
2645
2646
2647void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2648 Object* value) {
2649 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002650 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2651 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2652}
2653
2654
2655Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2656 ASSERT(0 <= id && id < kJSBuiltinsCount);
2657 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2658}
2659
2660
2661void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2662 Code* value) {
2663 ASSERT(0 <= id && id < kJSBuiltinsCount);
2664 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2665 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002666}
2667
2668
2669Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002670 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002671}
2672
2673
2674void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002675 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002676}
2677
2678
2679void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2680 visitor->VisitExternalReference(
2681 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2682}
2683
2684
2685ACCESSORS(JSValue, value, Object, kValueOffset)
2686
2687
2688JSValue* JSValue::cast(Object* obj) {
2689 ASSERT(obj->IsJSValue());
2690 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2691 return reinterpret_cast<JSValue*>(obj);
2692}
2693
2694
2695INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2696INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2697INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2698
2699
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700byte* Code::instruction_start() {
2701 return FIELD_ADDR(this, kHeaderSize);
2702}
2703
2704
2705int Code::body_size() {
2706 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2707}
2708
2709
2710byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002711 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712}
2713
2714
2715byte* Code::entry() {
2716 return instruction_start();
2717}
2718
2719
2720bool Code::contains(byte* pc) {
2721 return (instruction_start() <= pc) &&
2722 (pc < instruction_start() + instruction_size());
2723}
2724
2725
2726byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002727 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728}
2729
2730
2731ACCESSORS(JSArray, length, Object, kLengthOffset)
2732
2733
ager@chromium.org236ad962008-09-25 09:45:57 +00002734ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002735
2736
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002737JSRegExp::Type JSRegExp::TypeTag() {
2738 Object* data = this->data();
2739 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2740 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2741 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002742}
2743
2744
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002745int JSRegExp::CaptureCount() {
2746 switch (TypeTag()) {
2747 case ATOM:
2748 return 0;
2749 case IRREGEXP:
2750 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2751 default:
2752 UNREACHABLE();
2753 return -1;
2754 }
2755}
2756
2757
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002758JSRegExp::Flags JSRegExp::GetFlags() {
2759 ASSERT(this->data()->IsFixedArray());
2760 Object* data = this->data();
2761 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2762 return Flags(smi->value());
2763}
2764
2765
2766String* JSRegExp::Pattern() {
2767 ASSERT(this->data()->IsFixedArray());
2768 Object* data = this->data();
2769 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2770 return pattern;
2771}
2772
2773
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002774Object* JSRegExp::DataAt(int index) {
2775 ASSERT(TypeTag() != NOT_COMPILED);
2776 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002777}
2778
2779
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002780void JSRegExp::SetDataAt(int index, Object* value) {
2781 ASSERT(TypeTag() != NOT_COMPILED);
2782 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2783 FixedArray::cast(data())->set(index, value);
2784}
2785
2786
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002787JSObject::ElementsKind JSObject::GetElementsKind() {
2788 Array* array = elements();
2789 if (array->IsFixedArray()) {
2790 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2791 if (array->map() == Heap::fixed_array_map()) {
2792 return FAST_ELEMENTS;
2793 }
2794 ASSERT(array->IsDictionary());
2795 return DICTIONARY_ELEMENTS;
2796 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002797 if (array->IsExternalArray()) {
2798 switch (array->map()->instance_type()) {
2799 case EXTERNAL_BYTE_ARRAY_TYPE:
2800 return EXTERNAL_BYTE_ELEMENTS;
2801 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2802 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2803 case EXTERNAL_SHORT_ARRAY_TYPE:
2804 return EXTERNAL_SHORT_ELEMENTS;
2805 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2806 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2807 case EXTERNAL_INT_ARRAY_TYPE:
2808 return EXTERNAL_INT_ELEMENTS;
2809 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2810 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2811 default:
2812 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2813 return EXTERNAL_FLOAT_ELEMENTS;
2814 }
2815 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002816 ASSERT(array->IsPixelArray());
2817 return PIXEL_ELEMENTS;
2818}
2819
2820
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002821bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002822 return GetElementsKind() == FAST_ELEMENTS;
2823}
2824
2825
2826bool JSObject::HasDictionaryElements() {
2827 return GetElementsKind() == DICTIONARY_ELEMENTS;
2828}
2829
2830
2831bool JSObject::HasPixelElements() {
2832 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833}
2834
2835
ager@chromium.org3811b432009-10-28 14:53:37 +00002836bool JSObject::HasExternalArrayElements() {
2837 return (HasExternalByteElements() ||
2838 HasExternalUnsignedByteElements() ||
2839 HasExternalShortElements() ||
2840 HasExternalUnsignedShortElements() ||
2841 HasExternalIntElements() ||
2842 HasExternalUnsignedIntElements() ||
2843 HasExternalFloatElements());
2844}
2845
2846
2847bool JSObject::HasExternalByteElements() {
2848 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2849}
2850
2851
2852bool JSObject::HasExternalUnsignedByteElements() {
2853 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2854}
2855
2856
2857bool JSObject::HasExternalShortElements() {
2858 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2859}
2860
2861
2862bool JSObject::HasExternalUnsignedShortElements() {
2863 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2864}
2865
2866
2867bool JSObject::HasExternalIntElements() {
2868 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2869}
2870
2871
2872bool JSObject::HasExternalUnsignedIntElements() {
2873 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2874}
2875
2876
2877bool JSObject::HasExternalFloatElements() {
2878 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2879}
2880
2881
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882bool JSObject::HasNamedInterceptor() {
2883 return map()->has_named_interceptor();
2884}
2885
2886
2887bool JSObject::HasIndexedInterceptor() {
2888 return map()->has_indexed_interceptor();
2889}
2890
2891
ager@chromium.org5c838252010-02-19 08:53:10 +00002892bool JSObject::AllowsSetElementsLength() {
2893 bool result = elements()->IsFixedArray();
2894 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2895 return result;
2896}
2897
2898
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002899StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002900 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002901 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902}
2903
2904
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002905NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002906 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002907 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002908}
2909
2910
2911bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002912 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913}
2914
2915
2916uint32_t String::Hash() {
2917 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002918 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002919 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002920 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002921 return ComputeAndSetHash();
2922}
2923
2924
ager@chromium.org7c537e22008-10-16 08:43:32 +00002925StringHasher::StringHasher(int length)
2926 : length_(length),
2927 raw_running_hash_(0),
2928 array_index_(0),
2929 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2930 is_first_char_(true),
2931 is_valid_(true) { }
2932
2933
2934bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002935 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002936}
2937
2938
2939void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002940 // Use the Jenkins one-at-a-time hash function to update the hash
2941 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002942 raw_running_hash_ += c;
2943 raw_running_hash_ += (raw_running_hash_ << 10);
2944 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002945 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002946 if (is_array_index_) {
2947 if (c < '0' || c > '9') {
2948 is_array_index_ = false;
2949 } else {
2950 int d = c - '0';
2951 if (is_first_char_) {
2952 is_first_char_ = false;
2953 if (c == '0' && length_ > 1) {
2954 is_array_index_ = false;
2955 return;
2956 }
2957 }
2958 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2959 is_array_index_ = false;
2960 } else {
2961 array_index_ = array_index_ * 10 + d;
2962 }
2963 }
2964 }
2965}
2966
2967
2968void StringHasher::AddCharacterNoIndex(uc32 c) {
2969 ASSERT(!is_array_index());
2970 raw_running_hash_ += c;
2971 raw_running_hash_ += (raw_running_hash_ << 10);
2972 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2973}
2974
2975
2976uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002977 // Get the calculated raw hash value and do some more bit ops to distribute
2978 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002979 uint32_t result = raw_running_hash_;
2980 result += (result << 3);
2981 result ^= (result >> 11);
2982 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002983 if (result == 0) {
2984 result = 27;
2985 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002986 return result;
2987}
2988
2989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002991 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002992 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002993 return SlowAsArrayIndex(index);
2994}
2995
2996
2997Object* JSObject::GetPrototype() {
2998 return JSObject::cast(this)->map()->prototype();
2999}
3000
3001
3002PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3003 return GetPropertyAttributeWithReceiver(this, key);
3004}
3005
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003006// TODO(504): this may be useful in other places too where JSGlobalProxy
3007// is used.
3008Object* JSObject::BypassGlobalProxy() {
3009 if (IsJSGlobalProxy()) {
3010 Object* proto = GetPrototype();
3011 if (proto->IsNull()) return Heap::undefined_value();
3012 ASSERT(proto->IsJSGlobalObject());
3013 return proto;
3014 }
3015 return this;
3016}
3017
3018
3019bool JSObject::HasHiddenPropertiesObject() {
3020 ASSERT(!IsJSGlobalProxy());
3021 return GetPropertyAttributePostInterceptor(this,
3022 Heap::hidden_symbol(),
3023 false) != ABSENT;
3024}
3025
3026
3027Object* JSObject::GetHiddenPropertiesObject() {
3028 ASSERT(!IsJSGlobalProxy());
3029 PropertyAttributes attributes;
3030 return GetLocalPropertyPostInterceptor(this,
3031 Heap::hidden_symbol(),
3032 &attributes);
3033}
3034
3035
3036Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3037 ASSERT(!IsJSGlobalProxy());
3038 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3039 hidden_obj,
3040 DONT_ENUM);
3041}
3042
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043
3044bool JSObject::HasElement(uint32_t index) {
3045 return HasElementWithReceiver(this, index);
3046}
3047
3048
3049bool AccessorInfo::all_can_read() {
3050 return BooleanBit::get(flag(), kAllCanReadBit);
3051}
3052
3053
3054void AccessorInfo::set_all_can_read(bool value) {
3055 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3056}
3057
3058
3059bool AccessorInfo::all_can_write() {
3060 return BooleanBit::get(flag(), kAllCanWriteBit);
3061}
3062
3063
3064void AccessorInfo::set_all_can_write(bool value) {
3065 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3066}
3067
3068
ager@chromium.org870a0b62008-11-04 11:43:05 +00003069bool AccessorInfo::prohibits_overwriting() {
3070 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3071}
3072
3073
3074void AccessorInfo::set_prohibits_overwriting(bool value) {
3075 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3076}
3077
3078
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003079PropertyAttributes AccessorInfo::property_attributes() {
3080 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3081}
3082
3083
3084void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3085 ASSERT(AttributesField::is_valid(attributes));
3086 int rest_value = flag()->value() & ~AttributesField::mask();
3087 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3088}
3089
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003090template<typename Shape, typename Key>
3091void Dictionary<Shape, Key>::SetEntry(int entry,
3092 Object* key,
3093 Object* value,
3094 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003095 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003096 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003097 AssertNoAllocation no_gc;
3098 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003099 FixedArray::set(index, key, mode);
3100 FixedArray::set(index+1, value, mode);
3101 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102}
3103
3104
3105void Map::ClearCodeCache() {
3106 // No write barrier is needed since empty_fixed_array is not in new space.
3107 // Please note this function is used during marking:
3108 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003109 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3110 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111}
3112
3113
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003114void JSArray::EnsureSize(int required_size) {
3115 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003116 Array* elts = elements();
3117 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3118 if (elts->length() < required_size) {
3119 // Doubling in size would be overkill, but leave some slack to avoid
3120 // constantly growing.
3121 Expand(required_size + (required_size >> 3));
3122 // It's a performance benefit to keep a frequently used array in new-space.
3123 } else if (!Heap::new_space()->Contains(elts) &&
3124 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3125 // Expand will allocate a new backing store in new space even if the size
3126 // we asked for isn't larger than what we had before.
3127 Expand(required_size);
3128 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003129}
3130
3131
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003132void JSArray::set_length(Smi* length) {
3133 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3134}
3135
3136
ager@chromium.org7c537e22008-10-16 08:43:32 +00003137void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003138 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003139 set_elements(storage);
3140}
3141
3142
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003143Object* FixedArray::Copy() {
3144 if (length() == 0) return this;
3145 return Heap::CopyFixedArray(this);
3146}
3147
3148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003149#undef CAST_ACCESSOR
3150#undef INT_ACCESSORS
3151#undef SMI_ACCESSORS
3152#undef ACCESSORS
3153#undef FIELD_ADDR
3154#undef READ_FIELD
3155#undef WRITE_FIELD
3156#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003157#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003158#undef READ_MEMADDR_FIELD
3159#undef WRITE_MEMADDR_FIELD
3160#undef READ_DOUBLE_FIELD
3161#undef WRITE_DOUBLE_FIELD
3162#undef READ_INT_FIELD
3163#undef WRITE_INT_FIELD
3164#undef READ_SHORT_FIELD
3165#undef WRITE_SHORT_FIELD
3166#undef READ_BYTE_FIELD
3167#undef WRITE_BYTE_FIELD
3168
3169
3170} } // namespace v8::internal
3171
3172#endif // V8_OBJECTS_INL_H_