blob: c360fd7aeed068400864e02a5781ba7fef1a788a [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
94#define BOOL_ACCESSORS(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98 void holder::set_##name(bool value) { \
99 set_##field(BooleanBit::set(field(), offset, value)); \
100 }
101
102
103bool Object::IsSmi() {
104 return HAS_SMI_TAG(this);
105}
106
107
108bool Object::IsHeapObject() {
109 return HAS_HEAP_OBJECT_TAG(this);
110}
111
112
113bool Object::IsHeapNumber() {
114 return Object::IsHeapObject()
115 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
116}
117
118
119bool Object::IsString() {
120 return Object::IsHeapObject()
121 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
122}
123
124
ager@chromium.org870a0b62008-11-04 11:43:05 +0000125bool Object::IsSymbol() {
126 if (!this->IsHeapObject()) return false;
127 uint32_t type = HeapObject::cast(this)->map()->instance_type();
128 return (type & (kIsNotStringMask | kIsSymbolMask)) ==
129 (kStringTag | kSymbolTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130}
131
132
133bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000134 if (!this->IsHeapObject()) return false;
135 uint32_t type = HeapObject::cast(this)->map()->instance_type();
136 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
137 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000138}
139
140
ager@chromium.org870a0b62008-11-04 11:43:05 +0000141#ifdef DEBUG
142// These are for cast checks. If you need one of these in release
143// mode you should consider using a StringShape before moving it out
144// of the ifdef
145
146bool Object::IsSeqString() {
147 if (!IsString()) return false;
148 return StringShape(String::cast(this)).IsSequential();
149}
150
151
152bool Object::IsSeqAsciiString() {
153 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000154 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000155 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000156}
157
158
159bool Object::IsSeqTwoByteString() {
160 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000161 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000162 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163}
164
165
166bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000167 if (!IsString()) return false;
168 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169}
170
171
172bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000173 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000174 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000175 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
179bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000181 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000182 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000183}
184
185
ager@chromium.org870a0b62008-11-04 11:43:05 +0000186bool Object::IsSlicedString() {
187 if (!IsString()) return false;
188 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189}
190
191
ager@chromium.org870a0b62008-11-04 11:43:05 +0000192#endif // DEBUG
193
194
195StringShape::StringShape(String* str)
196 : type_(str->map()->instance_type()) {
197 set_valid();
198 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199}
200
201
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202StringShape::StringShape(Map* map)
203 : type_(map->instance_type()) {
204 set_valid();
205 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000206}
207
208
ager@chromium.org870a0b62008-11-04 11:43:05 +0000209StringShape::StringShape(InstanceType t)
210 : type_(static_cast<uint32_t>(t)) {
211 set_valid();
212 ASSERT((type_ & kIsNotStringMask) == kStringTag);
213}
214
215
216bool StringShape::IsSymbol() {
217 ASSERT(valid());
218 return (type_ & kIsSymbolMask) == kSymbolTag;
219}
220
221
ager@chromium.org5ec48922009-05-05 07:25:34 +0000222bool String::IsAsciiRepresentation() {
223 uint32_t type = map()->instance_type();
224 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
225 return SlicedString::cast(this)->buffer()->IsAsciiRepresentation();
226 }
227 if ((type & kStringRepresentationMask) == kConsStringTag &&
228 ConsString::cast(this)->second()->length() == 0) {
229 return ConsString::cast(this)->first()->IsAsciiRepresentation();
230 }
231 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000232}
233
234
ager@chromium.org5ec48922009-05-05 07:25:34 +0000235bool String::IsTwoByteRepresentation() {
236 uint32_t type = map()->instance_type();
237 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
238 return SlicedString::cast(this)->buffer()->IsTwoByteRepresentation();
239 } else if ((type & kStringRepresentationMask) == kConsStringTag &&
240 ConsString::cast(this)->second()->length() == 0) {
241 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
242 }
243 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000244}
245
246
247bool StringShape::IsCons() {
248 return (type_ & kStringRepresentationMask) == kConsStringTag;
249}
250
251
252bool StringShape::IsSliced() {
253 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
254}
255
256
257bool StringShape::IsExternal() {
258 return (type_ & kStringRepresentationMask) == kExternalStringTag;
259}
260
261
262bool StringShape::IsSequential() {
263 return (type_ & kStringRepresentationMask) == kSeqStringTag;
264}
265
266
267StringRepresentationTag StringShape::representation_tag() {
268 uint32_t tag = (type_ & kStringRepresentationMask);
269 return static_cast<StringRepresentationTag>(tag);
270}
271
272
273uint32_t StringShape::full_representation_tag() {
274 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
275}
276
277
278uint32_t StringShape::size_tag() {
279 return (type_ & kStringSizeMask);
280}
281
282
283bool StringShape::IsSequentialAscii() {
284 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
285}
286
287
288bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000289 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000290}
291
292
293bool StringShape::IsExternalAscii() {
294 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
295}
296
297
298bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000299 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000300}
301
302
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000303uc32 FlatStringReader::Get(int index) {
304 ASSERT(0 <= index && index <= length_);
305 if (is_ascii_) {
306 return static_cast<const byte*>(start_)[index];
307 } else {
308 return static_cast<const uc16*>(start_)[index];
309 }
310}
311
312
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000313bool Object::IsNumber() {
314 return IsSmi() || IsHeapNumber();
315}
316
317
318bool Object::IsByteArray() {
319 return Object::IsHeapObject()
320 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
321}
322
323
324bool Object::IsFailure() {
325 return HAS_FAILURE_TAG(this);
326}
327
328
329bool Object::IsRetryAfterGC() {
330 return HAS_FAILURE_TAG(this)
331 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
332}
333
334
ager@chromium.org7c537e22008-10-16 08:43:32 +0000335bool Object::IsOutOfMemoryFailure() {
336 return HAS_FAILURE_TAG(this)
337 && Failure::cast(this)->IsOutOfMemoryException();
338}
339
340
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000341bool Object::IsException() {
342 return this == Failure::Exception();
343}
344
345
346bool Object::IsJSObject() {
347 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000348 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000349}
350
351
ager@chromium.org32912102009-01-16 10:38:43 +0000352bool Object::IsJSContextExtensionObject() {
353 return IsHeapObject()
354 && (HeapObject::cast(this)->map()->instance_type() ==
355 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
356}
357
358
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000359bool Object::IsMap() {
360 return Object::IsHeapObject()
361 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
362}
363
364
365bool Object::IsFixedArray() {
366 return Object::IsHeapObject()
367 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
368}
369
370
371bool Object::IsDescriptorArray() {
372 return IsFixedArray();
373}
374
375
376bool Object::IsContext() {
377 return Object::IsHeapObject()
378 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000379 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000380 HeapObject::cast(this)->map() == Heap::global_context_map());
381}
382
383
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000384bool Object::IsCatchContext() {
385 return Object::IsHeapObject()
386 && HeapObject::cast(this)->map() == Heap::catch_context_map();
387}
388
389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000390bool Object::IsGlobalContext() {
391 return Object::IsHeapObject()
392 && HeapObject::cast(this)->map() == Heap::global_context_map();
393}
394
395
396bool Object::IsJSFunction() {
397 return Object::IsHeapObject()
398 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
399}
400
401
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000402template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000403 return obj->IsJSFunction();
404}
405
406
407bool Object::IsCode() {
408 return Object::IsHeapObject()
409 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
410}
411
412
413bool Object::IsOddball() {
414 return Object::IsHeapObject()
415 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
416}
417
418
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000419bool Object::IsJSGlobalPropertyCell() {
420 return Object::IsHeapObject()
421 && HeapObject::cast(this)->map()->instance_type()
422 == JS_GLOBAL_PROPERTY_CELL_TYPE;
423}
424
425
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000426bool Object::IsSharedFunctionInfo() {
427 return Object::IsHeapObject() &&
428 (HeapObject::cast(this)->map()->instance_type() ==
429 SHARED_FUNCTION_INFO_TYPE);
430}
431
432
433bool Object::IsJSValue() {
434 return Object::IsHeapObject()
435 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
436}
437
438
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000439bool Object::IsStringWrapper() {
440 return IsJSValue() && JSValue::cast(this)->value()->IsString();
441}
442
443
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444bool Object::IsProxy() {
445 return Object::IsHeapObject()
446 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
447}
448
449
450bool Object::IsBoolean() {
451 return IsTrue() || IsFalse();
452}
453
454
455bool Object::IsJSArray() {
456 return Object::IsHeapObject()
457 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
458}
459
460
ager@chromium.org236ad962008-09-25 09:45:57 +0000461bool Object::IsJSRegExp() {
462 return Object::IsHeapObject()
463 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
464}
465
466
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000467template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000468 return obj->IsJSArray();
469}
470
471
472bool Object::IsHashTable() {
473 return Object::IsHeapObject()
474 && HeapObject::cast(this)->map() == Heap::hash_table_map();
475}
476
477
478bool Object::IsDictionary() {
479 return IsHashTable() && this != Heap::symbol_table();
480}
481
482
483bool Object::IsSymbolTable() {
484 return IsHashTable() && this == Heap::symbol_table();
485}
486
487
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000488bool Object::IsCompilationCacheTable() {
489 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000490}
491
492
ager@chromium.org236ad962008-09-25 09:45:57 +0000493bool Object::IsMapCache() {
494 return IsHashTable();
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498bool Object::IsPrimitive() {
499 return IsOddball() || IsNumber() || IsString();
500}
501
502
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000503bool Object::IsJSGlobalProxy() {
504 bool result = IsHeapObject() &&
505 (HeapObject::cast(this)->map()->instance_type() ==
506 JS_GLOBAL_PROXY_TYPE);
507 ASSERT(!result || IsAccessCheckNeeded());
508 return result;
509}
510
511
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000512bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000513 if (!IsHeapObject()) return false;
514
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000515 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000516 return type == JS_GLOBAL_OBJECT_TYPE ||
517 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518}
519
520
521bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522 return IsHeapObject() &&
523 (HeapObject::cast(this)->map()->instance_type() ==
524 JS_GLOBAL_OBJECT_TYPE);
525}
526
527
528bool Object::IsJSBuiltinsObject() {
529 return IsHeapObject() &&
530 (HeapObject::cast(this)->map()->instance_type() ==
531 JS_BUILTINS_OBJECT_TYPE);
532}
533
534
535bool Object::IsUndetectableObject() {
536 return IsHeapObject()
537 && HeapObject::cast(this)->map()->is_undetectable();
538}
539
540
541bool Object::IsAccessCheckNeeded() {
542 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000543 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000544}
545
546
547bool Object::IsStruct() {
548 if (!IsHeapObject()) return false;
549 switch (HeapObject::cast(this)->map()->instance_type()) {
550#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
551 STRUCT_LIST(MAKE_STRUCT_CASE)
552#undef MAKE_STRUCT_CASE
553 default: return false;
554 }
555}
556
557
558#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
559 bool Object::Is##Name() { \
560 return Object::IsHeapObject() \
561 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
562 }
563 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
564#undef MAKE_STRUCT_PREDICATE
565
566
567bool Object::IsUndefined() {
568 return this == Heap::undefined_value();
569}
570
571
572bool Object::IsTheHole() {
573 return this == Heap::the_hole_value();
574}
575
576
577bool Object::IsNull() {
578 return this == Heap::null_value();
579}
580
581
582bool Object::IsTrue() {
583 return this == Heap::true_value();
584}
585
586
587bool Object::IsFalse() {
588 return this == Heap::false_value();
589}
590
591
592double Object::Number() {
593 ASSERT(IsNumber());
594 return IsSmi()
595 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
596 : reinterpret_cast<HeapNumber*>(this)->value();
597}
598
599
600
601Object* Object::ToSmi() {
602 if (IsSmi()) return this;
603 if (IsHeapNumber()) {
604 double value = HeapNumber::cast(this)->value();
605 int int_value = FastD2I(value);
606 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
607 return Smi::FromInt(int_value);
608 }
609 }
610 return Failure::Exception();
611}
612
613
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000614bool Object::HasSpecificClassOf(String* name) {
615 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
616}
617
618
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619Object* Object::GetElement(uint32_t index) {
620 return GetElementWithReceiver(this, index);
621}
622
623
624Object* Object::GetProperty(String* key) {
625 PropertyAttributes attributes;
626 return GetPropertyWithReceiver(this, key, &attributes);
627}
628
629
630Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
631 return GetPropertyWithReceiver(this, key, attributes);
632}
633
634
635#define FIELD_ADDR(p, offset) \
636 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
637
638#define READ_FIELD(p, offset) \
639 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
640
641#define WRITE_FIELD(p, offset, value) \
642 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
643
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645#define WRITE_BARRIER(object, offset) \
646 Heap::RecordWrite(object->address(), offset);
647
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000648// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000649// write due to the assert validating the written value.
650#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
651 if (mode == UPDATE_WRITE_BARRIER) { \
652 Heap::RecordWrite(object->address(), offset); \
653 } else { \
654 ASSERT(mode == SKIP_WRITE_BARRIER); \
655 ASSERT(Heap::InNewSpace(object) || \
656 !Heap::InNewSpace(READ_FIELD(object, offset))); \
657 }
658
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000659#define READ_DOUBLE_FIELD(p, offset) \
660 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
661
662#define WRITE_DOUBLE_FIELD(p, offset, value) \
663 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
664
665#define READ_INT_FIELD(p, offset) \
666 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
667
668#define WRITE_INT_FIELD(p, offset, value) \
669 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
670
ager@chromium.org3e875802009-06-29 08:26:34 +0000671#define READ_INTPTR_FIELD(p, offset) \
672 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
673
674#define WRITE_INTPTR_FIELD(p, offset, value) \
675 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
676
ager@chromium.org7c537e22008-10-16 08:43:32 +0000677#define READ_UINT32_FIELD(p, offset) \
678 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
679
680#define WRITE_UINT32_FIELD(p, offset, value) \
681 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683#define READ_SHORT_FIELD(p, offset) \
684 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
685
686#define WRITE_SHORT_FIELD(p, offset, value) \
687 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
688
689#define READ_BYTE_FIELD(p, offset) \
690 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
691
692#define WRITE_BYTE_FIELD(p, offset, value) \
693 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
694
695
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000696Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
697 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698}
699
700
701int Smi::value() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000702 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kSmiTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703}
704
705
706Smi* Smi::FromInt(int value) {
707 ASSERT(Smi::IsValid(value));
ager@chromium.org9085a012009-05-11 19:22:57 +0000708 intptr_t tagged_value =
709 (static_cast<intptr_t>(value) << kSmiTagSize) | kSmiTag;
710 return reinterpret_cast<Smi*>(tagged_value);
711}
712
713
714Smi* Smi::FromIntptr(intptr_t value) {
715 ASSERT(Smi::IsValid(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716 return reinterpret_cast<Smi*>((value << kSmiTagSize) | kSmiTag);
717}
718
719
720Failure::Type Failure::type() const {
721 return static_cast<Type>(value() & kFailureTypeTagMask);
722}
723
724
725bool Failure::IsInternalError() const {
726 return type() == INTERNAL_ERROR;
727}
728
729
730bool Failure::IsOutOfMemoryException() const {
731 return type() == OUT_OF_MEMORY_EXCEPTION;
732}
733
734
735int Failure::requested() const {
736 const int kShiftBits =
737 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
738 STATIC_ASSERT(kShiftBits >= 0);
739 ASSERT(type() == RETRY_AFTER_GC);
740 return value() >> kShiftBits;
741}
742
743
744AllocationSpace Failure::allocation_space() const {
745 ASSERT_EQ(RETRY_AFTER_GC, type());
746 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
747 & kSpaceTagMask);
748}
749
750
751Failure* Failure::InternalError() {
752 return Construct(INTERNAL_ERROR);
753}
754
755
756Failure* Failure::Exception() {
757 return Construct(EXCEPTION);
758}
759
760Failure* Failure::OutOfMemoryException() {
761 return Construct(OUT_OF_MEMORY_EXCEPTION);
762}
763
764
765int Failure::value() const {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000766 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000770Failure* Failure::RetryAfterGC(int requested_bytes) {
771 int requested = requested_bytes >> kObjectAlignmentBits;
772 int value = (requested << kSpaceTagSize) | NEW_SPACE;
773 ASSERT(value >> kSpaceTagSize == requested);
774 ASSERT(Smi::IsValid(value));
775 ASSERT(value == ((value << kFailureTypeTagSize) >> kFailureTypeTagSize));
776 ASSERT(Smi::IsValid(value << kFailureTypeTagSize));
777 return Construct(RETRY_AFTER_GC, value);
778}
779
780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781Failure* Failure::Construct(Type type, int value) {
782 int info = (value << kFailureTypeTagSize) | type;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000783 // TODO(X64): Stop using Smi validation for non-smi checks, even if they
784 // happen to be identical at the moment.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785 ASSERT(Smi::IsValid(info)); // Same validation check as in Smi
ager@chromium.org5ec48922009-05-05 07:25:34 +0000786 return reinterpret_cast<Failure*>(
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000787 (static_cast<intptr_t>(info) << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000788}
789
790
791bool Smi::IsValid(int value) {
792#ifdef DEBUG
793 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
794#endif
795 // To be representable as an tagged small integer, the two
796 // most-significant bits of 'value' must be either 00 or 11 due to
797 // sign-extension. To check this we add 01 to the two
798 // most-significant bits, and check if the most-significant bit is 0
799 //
800 // CAUTION: The original code below:
801 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
802 // may lead to incorrect results according to the C language spec, and
803 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
804 // compiler may produce undefined results in case of signed integer
805 // overflow. The computation must be done w/ unsigned ints.
806 bool result =
807 ((static_cast<unsigned int>(value) + 0x40000000U) & 0x80000000U) == 0;
808 ASSERT(result == in_range);
809 return result;
810}
811
812
ager@chromium.org9085a012009-05-11 19:22:57 +0000813bool Smi::IsIntptrValid(intptr_t value) {
814#ifdef DEBUG
815 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
816#endif
817 // See Smi::IsValid(int) for description.
818 bool result =
819 ((static_cast<uintptr_t>(value) + 0x40000000U) < 0x80000000U);
820 ASSERT(result == in_range);
821 return result;
822}
823
824
kasper.lund7276f142008-07-30 08:49:36 +0000825MapWord MapWord::FromMap(Map* map) {
826 return MapWord(reinterpret_cast<uintptr_t>(map));
827}
828
829
830Map* MapWord::ToMap() {
831 return reinterpret_cast<Map*>(value_);
832}
833
834
835bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000836 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000837}
838
839
840MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000841 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
842 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000843}
844
845
846HeapObject* MapWord::ToForwardingAddress() {
847 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000848 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000849}
850
851
852bool MapWord::IsMarked() {
853 return (value_ & kMarkingMask) == 0;
854}
855
856
857void MapWord::SetMark() {
858 value_ &= ~kMarkingMask;
859}
860
861
862void MapWord::ClearMark() {
863 value_ |= kMarkingMask;
864}
865
866
867bool MapWord::IsOverflowed() {
868 return (value_ & kOverflowMask) != 0;
869}
870
871
872void MapWord::SetOverflow() {
873 value_ |= kOverflowMask;
874}
875
876
877void MapWord::ClearOverflow() {
878 value_ &= ~kOverflowMask;
879}
880
881
882MapWord MapWord::EncodeAddress(Address map_address, int offset) {
883 // Offset is the distance in live bytes from the first live object in the
884 // same page. The offset between two objects in the same page should not
885 // exceed the object area size of a page.
886 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
887
888 int compact_offset = offset >> kObjectAlignmentBits;
889 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
890
891 Page* map_page = Page::FromAddress(map_address);
892 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
893
894 int map_page_offset =
895 map_page->Offset(map_address) >> kObjectAlignmentBits;
896
897 uintptr_t encoding =
898 (compact_offset << kForwardingOffsetShift) |
899 (map_page_offset << kMapPageOffsetShift) |
900 (map_page->mc_page_index << kMapPageIndexShift);
901 return MapWord(encoding);
902}
903
904
905Address MapWord::DecodeMapAddress(MapSpace* map_space) {
906 int map_page_index = (value_ & kMapPageIndexMask) >> kMapPageIndexShift;
907 ASSERT_MAP_PAGE_INDEX(map_page_index);
908
909 int map_page_offset =
910 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift)
911 << kObjectAlignmentBits;
912
913 return (map_space->PageAddress(map_page_index) + map_page_offset);
914}
915
916
917int MapWord::DecodeOffset() {
918 // The offset field is represented in the kForwardingOffsetBits
919 // most-significant bits.
920 int offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
921 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
922 return offset;
923}
924
925
926MapWord MapWord::FromEncodedAddress(Address address) {
927 return MapWord(reinterpret_cast<uintptr_t>(address));
928}
929
930
931Address MapWord::ToEncodedAddress() {
932 return reinterpret_cast<Address>(value_);
933}
934
935
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000936#ifdef DEBUG
937void HeapObject::VerifyObjectField(int offset) {
938 VerifyPointer(READ_FIELD(this, offset));
939}
940#endif
941
942
943Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +0000944 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945}
946
947
948void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +0000949 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950}
951
952
kasper.lund7276f142008-07-30 08:49:36 +0000953MapWord HeapObject::map_word() {
954 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
955}
956
957
958void HeapObject::set_map_word(MapWord map_word) {
959 // WRITE_FIELD does not update the remembered set, but there is no need
960 // here.
961 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
962}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963
964
965HeapObject* HeapObject::FromAddress(Address address) {
966 ASSERT_TAG_ALIGNED(address);
967 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
968}
969
970
971Address HeapObject::address() {
972 return reinterpret_cast<Address>(this) - kHeapObjectTag;
973}
974
975
976int HeapObject::Size() {
977 return SizeFromMap(map());
978}
979
980
981void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
982 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
983 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
984}
985
986
987void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
988 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
989}
990
991
kasper.lund7276f142008-07-30 08:49:36 +0000992bool HeapObject::IsMarked() {
993 return map_word().IsMarked();
994}
995
996
997void HeapObject::SetMark() {
998 ASSERT(!IsMarked());
999 MapWord first_word = map_word();
1000 first_word.SetMark();
1001 set_map_word(first_word);
1002}
1003
1004
1005void HeapObject::ClearMark() {
1006 ASSERT(IsMarked());
1007 MapWord first_word = map_word();
1008 first_word.ClearMark();
1009 set_map_word(first_word);
1010}
1011
1012
1013bool HeapObject::IsOverflowed() {
1014 return map_word().IsOverflowed();
1015}
1016
1017
1018void HeapObject::SetOverflow() {
1019 MapWord first_word = map_word();
1020 first_word.SetOverflow();
1021 set_map_word(first_word);
1022}
1023
1024
1025void HeapObject::ClearOverflow() {
1026 ASSERT(IsOverflowed());
1027 MapWord first_word = map_word();
1028 first_word.ClearOverflow();
1029 set_map_word(first_word);
1030}
1031
1032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033double HeapNumber::value() {
1034 return READ_DOUBLE_FIELD(this, kValueOffset);
1035}
1036
1037
1038void HeapNumber::set_value(double value) {
1039 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1040}
1041
1042
1043ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001044ACCESSORS(JSObject, elements, FixedArray, kElementsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045
1046
1047void JSObject::initialize_properties() {
1048 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1049 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1050}
1051
1052
1053void JSObject::initialize_elements() {
1054 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1055 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1056}
1057
1058
1059ACCESSORS(Oddball, to_string, String, kToStringOffset)
1060ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1061
1062
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001063ACCESSORS(JSGlobalPropertyCell, value, Object, kValueOffset)
1064
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065int JSObject::GetHeaderSize() {
1066 switch (map()->instance_type()) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001067 case JS_GLOBAL_PROXY_TYPE:
1068 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001069 case JS_GLOBAL_OBJECT_TYPE:
1070 return JSGlobalObject::kSize;
1071 case JS_BUILTINS_OBJECT_TYPE:
1072 return JSBuiltinsObject::kSize;
1073 case JS_FUNCTION_TYPE:
1074 return JSFunction::kSize;
1075 case JS_VALUE_TYPE:
1076 return JSValue::kSize;
1077 case JS_ARRAY_TYPE:
1078 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001079 case JS_REGEXP_TYPE:
1080 return JSValue::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001081 case JS_OBJECT_TYPE:
ager@chromium.org32912102009-01-16 10:38:43 +00001082 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001083 return JSObject::kHeaderSize;
1084 default:
1085 UNREACHABLE();
1086 return 0;
1087 }
1088}
1089
1090
1091int JSObject::GetInternalFieldCount() {
1092 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001093 // Make sure to adjust for the number of in-object properties. These
1094 // properties do contribute to the size, but are not internal fields.
1095 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1096 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001097}
1098
1099
1100Object* JSObject::GetInternalField(int index) {
1101 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001102 // Internal objects do follow immediately after the header, whereas in-object
1103 // properties are at the end of the object. Therefore there is no need
1104 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1106}
1107
1108
1109void JSObject::SetInternalField(int index, Object* value) {
1110 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001111 // Internal objects do follow immediately after the header, whereas in-object
1112 // properties are at the end of the object. Therefore there is no need
1113 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114 int offset = GetHeaderSize() + (kPointerSize * index);
1115 WRITE_FIELD(this, offset, value);
1116 WRITE_BARRIER(this, offset);
1117}
1118
1119
ager@chromium.org7c537e22008-10-16 08:43:32 +00001120// Access fast-case object properties at index. The use of these routines
1121// is needed to correctly distinguish between properties stored in-object and
1122// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001123Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001124 // Adjust for the number of properties stored in the object.
1125 index -= map()->inobject_properties();
1126 if (index < 0) {
1127 int offset = map()->instance_size() + (index * kPointerSize);
1128 return READ_FIELD(this, offset);
1129 } else {
1130 ASSERT(index < properties()->length());
1131 return properties()->get(index);
1132 }
1133}
1134
1135
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001136Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001137 // Adjust for the number of properties stored in the object.
1138 index -= map()->inobject_properties();
1139 if (index < 0) {
1140 int offset = map()->instance_size() + (index * kPointerSize);
1141 WRITE_FIELD(this, offset, value);
1142 WRITE_BARRIER(this, offset);
1143 } else {
1144 ASSERT(index < properties()->length());
1145 properties()->set(index, value);
1146 }
1147 return value;
1148}
1149
1150
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001151Object* JSObject::InObjectPropertyAt(int index) {
1152 // Adjust for the number of properties stored in the object.
1153 index -= map()->inobject_properties();
1154 ASSERT(index < 0);
1155 int offset = map()->instance_size() + (index * kPointerSize);
1156 return READ_FIELD(this, offset);
1157}
1158
1159
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001160Object* JSObject::InObjectPropertyAtPut(int index,
1161 Object* value,
1162 WriteBarrierMode mode) {
1163 // Adjust for the number of properties stored in the object.
1164 index -= map()->inobject_properties();
1165 ASSERT(index < 0);
1166 int offset = map()->instance_size() + (index * kPointerSize);
1167 WRITE_FIELD(this, offset, value);
1168 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1169 return value;
1170}
1171
1172
1173
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001175 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001176 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001177 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001178 }
1179}
1180
1181
1182void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001183 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001184 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001185 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186 }
1187}
1188
1189
1190bool JSObject::HasFastProperties() {
1191 return !properties()->IsDictionary();
1192}
1193
1194
1195bool Array::IndexFromObject(Object* object, uint32_t* index) {
1196 if (object->IsSmi()) {
1197 int value = Smi::cast(object)->value();
1198 if (value < 0) return false;
1199 *index = value;
1200 return true;
1201 }
1202 if (object->IsHeapNumber()) {
1203 double value = HeapNumber::cast(object)->value();
1204 uint32_t uint_value = static_cast<uint32_t>(value);
1205 if (value == static_cast<double>(uint_value)) {
1206 *index = uint_value;
1207 return true;
1208 }
1209 }
1210 return false;
1211}
1212
1213
1214bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1215 if (!this->IsJSValue()) return false;
1216
1217 JSValue* js_value = JSValue::cast(this);
1218 if (!js_value->value()->IsString()) return false;
1219
1220 String* str = String::cast(js_value->value());
1221 if (index >= (uint32_t)str->length()) return false;
1222
1223 return true;
1224}
1225
1226
1227Object* FixedArray::get(int index) {
1228 ASSERT(index >= 0 && index < this->length());
1229 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1230}
1231
1232
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001233void FixedArray::set(int index, Smi* value) {
1234 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1235 int offset = kHeaderSize + index * kPointerSize;
1236 WRITE_FIELD(this, offset, value);
1237}
1238
1239
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001240void FixedArray::set(int index, Object* value) {
1241 ASSERT(index >= 0 && index < this->length());
1242 int offset = kHeaderSize + index * kPointerSize;
1243 WRITE_FIELD(this, offset, value);
1244 WRITE_BARRIER(this, offset);
1245}
1246
1247
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001248WriteBarrierMode HeapObject::GetWriteBarrierMode() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001249 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1250 return UPDATE_WRITE_BARRIER;
1251}
1252
1253
1254void FixedArray::set(int index,
1255 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001256 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001257 ASSERT(index >= 0 && index < this->length());
1258 int offset = kHeaderSize + index * kPointerSize;
1259 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001260 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261}
1262
1263
1264void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1265 ASSERT(index >= 0 && index < array->length());
1266 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1267}
1268
1269
1270void FixedArray::set_undefined(int index) {
1271 ASSERT(index >= 0 && index < this->length());
1272 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1273 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1274 Heap::undefined_value());
1275}
1276
1277
ager@chromium.org236ad962008-09-25 09:45:57 +00001278void FixedArray::set_null(int index) {
1279 ASSERT(index >= 0 && index < this->length());
1280 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1281 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1282}
1283
1284
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001285void FixedArray::set_the_hole(int index) {
1286 ASSERT(index >= 0 && index < this->length());
1287 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1288 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1289}
1290
1291
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001292bool DescriptorArray::IsEmpty() {
1293 ASSERT(this == Heap::empty_descriptor_array() ||
1294 this->length() > 2);
1295 return this == Heap::empty_descriptor_array();
1296}
1297
1298
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001299void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1300 Object* tmp = array->get(first);
1301 fast_set(array, first, array->get(second));
1302 fast_set(array, second, tmp);
1303}
1304
1305
1306int DescriptorArray::Search(String* name) {
1307 SLOW_ASSERT(IsSortedNoDuplicates());
1308
1309 // Check for empty descriptor array.
1310 int nof = number_of_descriptors();
1311 if (nof == 0) return kNotFound;
1312
1313 // Fast case: do linear search for small arrays.
1314 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001315 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001316 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001317 }
1318
1319 // Slow case: perform binary search.
1320 return BinarySearch(name, 0, nof - 1);
1321}
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324String* DescriptorArray::GetKey(int descriptor_number) {
1325 ASSERT(descriptor_number < number_of_descriptors());
1326 return String::cast(get(ToKeyIndex(descriptor_number)));
1327}
1328
1329
1330Object* DescriptorArray::GetValue(int descriptor_number) {
1331 ASSERT(descriptor_number < number_of_descriptors());
1332 return GetContentArray()->get(ToValueIndex(descriptor_number));
1333}
1334
1335
1336Smi* DescriptorArray::GetDetails(int descriptor_number) {
1337 ASSERT(descriptor_number < number_of_descriptors());
1338 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1339}
1340
1341
1342void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1343 desc->Init(GetKey(descriptor_number),
1344 GetValue(descriptor_number),
1345 GetDetails(descriptor_number));
1346}
1347
1348
1349void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1350 // Range check.
1351 ASSERT(descriptor_number < number_of_descriptors());
1352
1353 // Make sure non of the elements in desc are in new space.
1354 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1355 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1356
1357 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1358 FixedArray* content_array = GetContentArray();
1359 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1360 fast_set(content_array, ToDetailsIndex(descriptor_number),
1361 desc->GetDetails().AsSmi());
1362}
1363
1364
1365void DescriptorArray::Swap(int first, int second) {
1366 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1367 FixedArray* content_array = GetContentArray();
1368 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1369 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1370}
1371
1372
1373bool Dictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001374 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001375 if (!max_index_object->IsSmi()) return false;
1376 return 0 !=
1377 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1378}
1379
1380
1381uint32_t Dictionary::max_number_key() {
1382 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384 if (!max_index_object->IsSmi()) return 0;
1385 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1386 return value >> kRequiresSlowElementsTagSize;
1387}
1388
1389
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001390void Dictionary::set_requires_slow_elements() {
1391 set(kMaxNumberKeyIndex,
1392 Smi::FromInt(kRequiresSlowElementsMask),
1393 SKIP_WRITE_BARRIER);
1394}
1395
1396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001397// ------------------------------------
1398// Cast operations
1399
1400
1401CAST_ACCESSOR(FixedArray)
1402CAST_ACCESSOR(DescriptorArray)
1403CAST_ACCESSOR(Dictionary)
1404CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001405CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001406CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407CAST_ACCESSOR(String)
1408CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001409CAST_ACCESSOR(SeqAsciiString)
1410CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411CAST_ACCESSOR(ConsString)
1412CAST_ACCESSOR(SlicedString)
1413CAST_ACCESSOR(ExternalString)
1414CAST_ACCESSOR(ExternalAsciiString)
1415CAST_ACCESSOR(ExternalTwoByteString)
1416CAST_ACCESSOR(JSObject)
1417CAST_ACCESSOR(Smi)
1418CAST_ACCESSOR(Failure)
1419CAST_ACCESSOR(HeapObject)
1420CAST_ACCESSOR(HeapNumber)
1421CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001422CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423CAST_ACCESSOR(SharedFunctionInfo)
1424CAST_ACCESSOR(Map)
1425CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001426CAST_ACCESSOR(GlobalObject)
1427CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001428CAST_ACCESSOR(JSGlobalObject)
1429CAST_ACCESSOR(JSBuiltinsObject)
1430CAST_ACCESSOR(Code)
1431CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001432CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433CAST_ACCESSOR(Proxy)
1434CAST_ACCESSOR(ByteArray)
1435CAST_ACCESSOR(Struct)
1436
1437
1438#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1439 STRUCT_LIST(MAKE_STRUCT_CAST)
1440#undef MAKE_STRUCT_CAST
1441
1442template <int prefix_size, int elem_size>
1443HashTable<prefix_size, elem_size>* HashTable<prefix_size, elem_size>::cast(
1444 Object* obj) {
1445 ASSERT(obj->IsHashTable());
1446 return reinterpret_cast<HashTable*>(obj);
1447}
1448
1449
1450INT_ACCESSORS(Array, length, kLengthOffset)
1451
1452
1453bool String::Equals(String* other) {
1454 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001455 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1456 return false;
1457 }
1458 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459}
1460
1461
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001462int String::length() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463 uint32_t len = READ_INT_FIELD(this, kLengthOffset);
1464
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001465 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1466 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1467 ASSERT(kLongStringTag == 0);
1468
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001469 return len >> (StringShape(this).size_tag() + kLongLengthShift);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001470}
1471
1472
1473void String::set_length(int value) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001474 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1475 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1476 ASSERT(kLongStringTag == 0);
1477
1478 WRITE_INT_FIELD(this,
1479 kLengthOffset,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001480 value << (StringShape(this).size_tag() + kLongLengthShift));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481}
1482
1483
ager@chromium.org7c537e22008-10-16 08:43:32 +00001484uint32_t String::length_field() {
1485 return READ_UINT32_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001486}
1487
1488
ager@chromium.org7c537e22008-10-16 08:43:32 +00001489void String::set_length_field(uint32_t value) {
1490 WRITE_UINT32_FIELD(this, kLengthOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491}
1492
1493
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001494Object* String::TryFlattenIfNotFlat() {
ager@chromium.org236ad962008-09-25 09:45:57 +00001495 // We don't need to flatten strings that are already flat. Since this code
1496 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001497 if (!IsFlat()) {
1498 return TryFlatten();
ager@chromium.org236ad962008-09-25 09:45:57 +00001499 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001500 return this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001501}
1502
1503
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001504uint16_t String::Get(int index) {
1505 ASSERT(index >= 0 && index < length());
1506 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001507 case kSeqStringTag | kAsciiStringTag:
1508 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1509 case kSeqStringTag | kTwoByteStringTag:
1510 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1511 case kConsStringTag | kAsciiStringTag:
1512 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001514 case kSlicedStringTag | kAsciiStringTag:
1515 case kSlicedStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516 return SlicedString::cast(this)->SlicedStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001517 case kExternalStringTag | kAsciiStringTag:
1518 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1519 case kExternalStringTag | kTwoByteStringTag:
1520 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 default:
1522 break;
1523 }
1524
1525 UNREACHABLE();
1526 return 0;
1527}
1528
1529
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001530void String::Set(int index, uint16_t value) {
1531 ASSERT(index >= 0 && index < length());
1532 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001533
ager@chromium.org5ec48922009-05-05 07:25:34 +00001534 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001535 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1536 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537}
1538
1539
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001540bool String::IsFlat() {
1541 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001542 case kConsStringTag: {
1543 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001544 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001545 return second->length() == 0;
1546 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001547 case kSlicedStringTag: {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001548 StringRepresentationTag tag =
1549 StringShape(SlicedString::cast(this)->buffer()).representation_tag();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001550 return tag == kSeqStringTag || tag == kExternalStringTag;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001551 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001552 default:
1553 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001554 }
1555}
1556
1557
ager@chromium.org7c537e22008-10-16 08:43:32 +00001558uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001559 ASSERT(index >= 0 && index < length());
1560 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1561}
1562
1563
ager@chromium.org7c537e22008-10-16 08:43:32 +00001564void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1566 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1567 static_cast<byte>(value));
1568}
1569
1570
ager@chromium.org7c537e22008-10-16 08:43:32 +00001571Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001572 return FIELD_ADDR(this, kHeaderSize);
1573}
1574
1575
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001576char* SeqAsciiString::GetChars() {
1577 return reinterpret_cast<char*>(GetCharsAddress());
1578}
1579
1580
ager@chromium.org7c537e22008-10-16 08:43:32 +00001581Address SeqTwoByteString::GetCharsAddress() {
1582 return FIELD_ADDR(this, kHeaderSize);
1583}
1584
1585
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001586uc16* SeqTwoByteString::GetChars() {
1587 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1588}
1589
1590
ager@chromium.org7c537e22008-10-16 08:43:32 +00001591uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001592 ASSERT(index >= 0 && index < length());
1593 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1594}
1595
1596
ager@chromium.org7c537e22008-10-16 08:43:32 +00001597void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001598 ASSERT(index >= 0 && index < length());
1599 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1600}
1601
1602
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001603int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1605
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001606 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1607 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1608 ASSERT(kLongStringTag == 0);
1609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610 // Use the map (and not 'this') to compute the size tag, since
1611 // TwoByteStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001612 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614 return SizeFor(length);
1615}
1616
1617
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001618int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1620
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001621 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1622 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1623 ASSERT(kLongStringTag == 0);
1624
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625 // Use the map (and not 'this') to compute the size tag, since
1626 // AsciiStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001627 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001628
1629 return SizeFor(length);
1630}
1631
1632
ager@chromium.org870a0b62008-11-04 11:43:05 +00001633String* ConsString::first() {
1634 return String::cast(READ_FIELD(this, kFirstOffset));
1635}
1636
1637
1638Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639 return READ_FIELD(this, kFirstOffset);
1640}
1641
1642
ager@chromium.org870a0b62008-11-04 11:43:05 +00001643void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001645 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001646}
1647
1648
ager@chromium.org870a0b62008-11-04 11:43:05 +00001649String* ConsString::second() {
1650 return String::cast(READ_FIELD(this, kSecondOffset));
1651}
1652
1653
1654Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655 return READ_FIELD(this, kSecondOffset);
1656}
1657
1658
ager@chromium.org870a0b62008-11-04 11:43:05 +00001659void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001660 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001661 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001662}
1663
1664
ager@chromium.org870a0b62008-11-04 11:43:05 +00001665String* SlicedString::buffer() {
1666 return String::cast(READ_FIELD(this, kBufferOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667}
1668
1669
ager@chromium.org870a0b62008-11-04 11:43:05 +00001670void SlicedString::set_buffer(String* buffer) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671 WRITE_FIELD(this, kBufferOffset, buffer);
1672 WRITE_BARRIER(this, kBufferOffset);
1673}
1674
1675
1676int SlicedString::start() {
1677 return READ_INT_FIELD(this, kStartOffset);
1678}
1679
1680
1681void SlicedString::set_start(int start) {
1682 WRITE_INT_FIELD(this, kStartOffset, start);
1683}
1684
1685
1686ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1687 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1688}
1689
1690
1691void ExternalAsciiString::set_resource(
1692 ExternalAsciiString::Resource* resource) {
1693 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1694}
1695
1696
ager@chromium.org6f10e412009-02-13 10:11:16 +00001697Map* ExternalAsciiString::StringMap(int length) {
1698 Map* map;
1699 // Number of characters: determines the map.
1700 if (length <= String::kMaxShortStringSize) {
1701 map = Heap::short_external_ascii_string_map();
1702 } else if (length <= String::kMaxMediumStringSize) {
1703 map = Heap::medium_external_ascii_string_map();
1704 } else {
1705 map = Heap::long_external_ascii_string_map();
1706 }
1707 return map;
1708}
1709
1710
1711Map* ExternalAsciiString::SymbolMap(int length) {
1712 Map* map;
1713 // Number of characters: determines the map.
1714 if (length <= String::kMaxShortStringSize) {
1715 map = Heap::short_external_ascii_symbol_map();
1716 } else if (length <= String::kMaxMediumStringSize) {
1717 map = Heap::medium_external_ascii_symbol_map();
1718 } else {
1719 map = Heap::long_external_ascii_symbol_map();
1720 }
1721 return map;
1722}
1723
1724
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1726 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1727}
1728
1729
1730void ExternalTwoByteString::set_resource(
1731 ExternalTwoByteString::Resource* resource) {
1732 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1733}
1734
1735
ager@chromium.org6f10e412009-02-13 10:11:16 +00001736Map* ExternalTwoByteString::StringMap(int length) {
1737 Map* map;
1738 // Number of characters: determines the map.
1739 if (length <= String::kMaxShortStringSize) {
1740 map = Heap::short_external_string_map();
1741 } else if (length <= String::kMaxMediumStringSize) {
1742 map = Heap::medium_external_string_map();
1743 } else {
1744 map = Heap::long_external_string_map();
1745 }
1746 return map;
1747}
1748
1749
1750Map* ExternalTwoByteString::SymbolMap(int length) {
1751 Map* map;
1752 // Number of characters: determines the map.
1753 if (length <= String::kMaxShortStringSize) {
1754 map = Heap::short_external_symbol_map();
1755 } else if (length <= String::kMaxMediumStringSize) {
1756 map = Heap::medium_external_symbol_map();
1757 } else {
1758 map = Heap::long_external_symbol_map();
1759 }
1760 return map;
1761}
1762
1763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001764byte ByteArray::get(int index) {
1765 ASSERT(index >= 0 && index < this->length());
1766 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1767}
1768
1769
1770void ByteArray::set(int index, byte value) {
1771 ASSERT(index >= 0 && index < this->length());
1772 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1773}
1774
1775
1776int ByteArray::get_int(int index) {
1777 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1778 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1779}
1780
1781
1782ByteArray* ByteArray::FromDataStartAddress(Address address) {
1783 ASSERT_TAG_ALIGNED(address);
1784 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1785}
1786
1787
1788Address ByteArray::GetDataStartAddress() {
1789 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1790}
1791
1792
1793int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001794 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
1795}
1796
1797
1798int Map::inobject_properties() {
1799 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800}
1801
1802
1803int HeapObject::SizeFromMap(Map* map) {
1804 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001805 // Only inline the most frequent cases.
1806 if (instance_type == JS_OBJECT_TYPE ||
1807 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
1808 (kStringTag | kConsStringTag) ||
1809 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 if (instance_type == FIXED_ARRAY_TYPE) {
1811 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
1812 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001813 if (instance_type == BYTE_ARRAY_TYPE) {
1814 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
1815 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 // Otherwise do the general size computation.
1817 return SlowSizeFromMap(map);
1818}
1819
1820
1821void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001822 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00001823 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 ASSERT(0 <= value && value < 256);
1825 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
1826}
1827
1828
ager@chromium.org7c537e22008-10-16 08:43:32 +00001829void Map::set_inobject_properties(int value) {
1830 ASSERT(0 <= value && value < 256);
1831 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
1832}
1833
1834
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835InstanceType Map::instance_type() {
1836 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
1837}
1838
1839
1840void Map::set_instance_type(InstanceType value) {
1841 ASSERT(0 <= value && value < 256);
1842 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
1843}
1844
1845
1846int Map::unused_property_fields() {
1847 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
1848}
1849
1850
1851void Map::set_unused_property_fields(int value) {
1852 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
1853}
1854
1855
1856byte Map::bit_field() {
1857 return READ_BYTE_FIELD(this, kBitFieldOffset);
1858}
1859
1860
1861void Map::set_bit_field(byte value) {
1862 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
1863}
1864
1865
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00001866byte Map::bit_field2() {
1867 return READ_BYTE_FIELD(this, kBitField2Offset);
1868}
1869
1870
1871void Map::set_bit_field2(byte value) {
1872 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
1873}
1874
1875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876void Map::set_non_instance_prototype(bool value) {
1877 if (value) {
1878 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
1879 } else {
1880 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
1881 }
1882}
1883
1884
1885bool Map::has_non_instance_prototype() {
1886 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
1887}
1888
1889
ager@chromium.org870a0b62008-11-04 11:43:05 +00001890void Map::set_is_access_check_needed(bool access_check_needed) {
1891 if (access_check_needed) {
1892 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
1893 } else {
1894 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
1895 }
1896}
1897
1898
1899bool Map::is_access_check_needed() {
1900 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
1901}
1902
1903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904Code::Flags Code::flags() {
1905 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
1906}
1907
1908
1909void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001910 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911 // Make sure that all call stubs have an arguments count.
1912 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
1913 ExtractArgumentsCountFromFlags(flags) >= 0);
1914 WRITE_INT_FIELD(this, kFlagsOffset, flags);
1915}
1916
1917
1918Code::Kind Code::kind() {
1919 return ExtractKindFromFlags(flags());
1920}
1921
1922
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001923InLoopFlag Code::ic_in_loop() {
1924 return ExtractICInLoopFromFlags(flags());
1925}
1926
1927
kasper.lund7276f142008-07-30 08:49:36 +00001928InlineCacheState Code::ic_state() {
1929 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930 // Only allow uninitialized or debugger states for non-IC code
1931 // objects. This is used in the debugger to determine whether or not
1932 // a call to code object has been replaced with a debug break call.
1933 ASSERT(is_inline_cache_stub() ||
1934 result == UNINITIALIZED ||
1935 result == DEBUG_BREAK ||
1936 result == DEBUG_PREPARE_STEP_IN);
1937 return result;
1938}
1939
1940
1941PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00001942 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001943 return ExtractTypeFromFlags(flags());
1944}
1945
1946
1947int Code::arguments_count() {
1948 ASSERT(is_call_stub() || kind() == STUB);
1949 return ExtractArgumentsCountFromFlags(flags());
1950}
1951
1952
1953CodeStub::Major Code::major_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001954 ASSERT(kind() == STUB);
kasper.lund7276f142008-07-30 08:49:36 +00001955 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
1956 kStubMajorKeyOffset));
1957}
1958
1959
1960void Code::set_major_key(CodeStub::Major major) {
1961 ASSERT(kind() == STUB);
1962 ASSERT(0 <= major && major < 256);
1963 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
1967bool Code::is_inline_cache_stub() {
1968 Kind kind = this->kind();
1969 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
1970}
1971
1972
1973Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001974 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00001975 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976 PropertyType type,
1977 int argc) {
1978 // Compute the bit mask.
1979 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001980 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00001981 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001982 bits |= type << kFlagsTypeShift;
1983 bits |= argc << kFlagsArgumentsCountShift;
1984 // Cast to flags and validate result before returning it.
1985 Flags result = static_cast<Flags>(bits);
1986 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00001987 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001988 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001989 ASSERT(ExtractTypeFromFlags(result) == type);
1990 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
1991 return result;
1992}
1993
1994
1995Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
1996 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001997 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001999 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002000}
2001
2002
2003Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2004 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2005 return static_cast<Kind>(bits);
2006}
2007
2008
kasper.lund7276f142008-07-30 08:49:36 +00002009InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2010 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011 return static_cast<InlineCacheState>(bits);
2012}
2013
2014
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002015InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2016 int bits = (flags & kFlagsICInLoopMask);
2017 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2018}
2019
2020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2022 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2023 return static_cast<PropertyType>(bits);
2024}
2025
2026
2027int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2028 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2029}
2030
2031
2032Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2033 int bits = flags & ~kFlagsTypeMask;
2034 return static_cast<Flags>(bits);
2035}
2036
2037
ager@chromium.org8bb60582008-12-11 12:02:20 +00002038Code* Code::GetCodeFromTargetAddress(Address address) {
2039 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2040 // GetCodeFromTargetAddress might be called when marking objects during mark
2041 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2042 // Code::cast. Code::cast does not work when the object's map is
2043 // marked.
2044 Code* result = reinterpret_cast<Code*>(code);
2045 return result;
2046}
2047
2048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049Object* Map::prototype() {
2050 return READ_FIELD(this, kPrototypeOffset);
2051}
2052
2053
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002054void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 ASSERT(value->IsNull() || value->IsJSObject());
2056 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002057 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058}
2059
2060
2061ACCESSORS(Map, instance_descriptors, DescriptorArray,
2062 kInstanceDescriptorsOffset)
2063ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
2064ACCESSORS(Map, constructor, Object, kConstructorOffset)
2065
2066ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2067ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2068
2069ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2070ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002071ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002072
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002073ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002074
2075ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2076ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2077ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2078ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2079ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2080
2081ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2082ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2083ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2084
2085ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2086ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2087ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2088ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2089ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2090ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2091
2092ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2093ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2094
2095ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2096ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2097
2098ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2099ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2101 kPropertyAccessorsOffset)
2102ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2103 kPrototypeTemplateOffset)
2104ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2105ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2106 kNamedPropertyHandlerOffset)
2107ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2108 kIndexedPropertyHandlerOffset)
2109ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2110 kInstanceTemplateOffset)
2111ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2112ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002113ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2114 kInstanceCallHandlerOffset)
2115ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2116 kAccessCheckInfoOffset)
2117ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2118
2119ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002120ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2121 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122
2123ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2124ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2125
2126ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2127
2128ACCESSORS(Script, source, Object, kSourceOffset)
2129ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002130ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2132ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002133ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002134ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2136ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002137ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
iposva@chromium.org245aa852009-02-10 00:49:54 +00002138ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002139ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
2140ACCESSORS(Script, eval_from_instructions_offset, Smi,
2141 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002143#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2145ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2146ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2147ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2148
2149ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2150ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2151ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2152ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002153#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002155ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2157ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2158 kInstanceClassNameOffset)
2159ACCESSORS(SharedFunctionInfo, function_data, Object,
2160 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2162ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002163ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002164
2165BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2166 kHiddenPrototypeBit)
2167BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2168BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2169 kNeedsAccessCheckBit)
2170BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2171 kIsExpressionBit)
2172BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2173 kIsTopLevelBit)
2174
2175INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2176INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2177 kFormalParameterCountOffset)
2178INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2179 kExpectedNofPropertiesOffset)
2180INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2181 kStartPositionAndTypeOffset)
2182INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2183INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2184 kFunctionTokenPositionOffset)
2185
2186
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002187void SharedFunctionInfo::DontAdaptArguments() {
2188 ASSERT(code()->kind() == Code::BUILTIN);
2189 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2190}
2191
2192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193int SharedFunctionInfo::start_position() {
2194 return start_position_and_type() >> kStartPositionShift;
2195}
2196
2197
2198void SharedFunctionInfo::set_start_position(int start_position) {
2199 set_start_position_and_type((start_position << kStartPositionShift)
2200 | (start_position_and_type() & ~kStartPositionMask));
2201}
2202
2203
2204Code* SharedFunctionInfo::code() {
2205 return Code::cast(READ_FIELD(this, kCodeOffset));
2206}
2207
2208
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002209void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002210 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002211 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212}
2213
2214
2215bool SharedFunctionInfo::is_compiled() {
2216 // TODO(1242782): Create a code kind for uncompiled code.
2217 return code()->kind() != Code::STUB;
2218}
2219
2220
2221bool JSFunction::IsBoilerplate() {
2222 return map() == Heap::boilerplate_function_map();
2223}
2224
2225
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002226bool JSObject::IsLoaded() {
2227 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228}
2229
2230
2231Code* JSFunction::code() {
2232 return shared()->code();
2233}
2234
2235
2236void JSFunction::set_code(Code* value) {
2237 shared()->set_code(value);
2238}
2239
2240
2241Context* JSFunction::context() {
2242 return Context::cast(READ_FIELD(this, kContextOffset));
2243}
2244
2245
2246Object* JSFunction::unchecked_context() {
2247 return READ_FIELD(this, kContextOffset);
2248}
2249
2250
2251void JSFunction::set_context(Object* value) {
2252 ASSERT(value == Heap::undefined_value() || value->IsContext());
2253 WRITE_FIELD(this, kContextOffset, value);
2254 WRITE_BARRIER(this, kContextOffset);
2255}
2256
2257ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2258 kPrototypeOrInitialMapOffset)
2259
2260
2261Map* JSFunction::initial_map() {
2262 return Map::cast(prototype_or_initial_map());
2263}
2264
2265
2266void JSFunction::set_initial_map(Map* value) {
2267 set_prototype_or_initial_map(value);
2268}
2269
2270
2271bool JSFunction::has_initial_map() {
2272 return prototype_or_initial_map()->IsMap();
2273}
2274
2275
2276bool JSFunction::has_instance_prototype() {
2277 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2278}
2279
2280
2281bool JSFunction::has_prototype() {
2282 return map()->has_non_instance_prototype() || has_instance_prototype();
2283}
2284
2285
2286Object* JSFunction::instance_prototype() {
2287 ASSERT(has_instance_prototype());
2288 if (has_initial_map()) return initial_map()->prototype();
2289 // When there is no initial map and the prototype is a JSObject, the
2290 // initial map field is used for the prototype field.
2291 return prototype_or_initial_map();
2292}
2293
2294
2295Object* JSFunction::prototype() {
2296 ASSERT(has_prototype());
2297 // If the function's prototype property has been set to a non-JSObject
2298 // value, that value is stored in the constructor field of the map.
2299 if (map()->has_non_instance_prototype()) return map()->constructor();
2300 return instance_prototype();
2301}
2302
2303
2304bool JSFunction::is_compiled() {
2305 return shared()->is_compiled();
2306}
2307
2308
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002309int JSFunction::NumberOfLiterals() {
2310 return literals()->length();
2311}
2312
2313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002314Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2315 ASSERT(0 <= id && id < kJSBuiltinsCount);
2316 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2317}
2318
2319
2320void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2321 Object* value) {
2322 ASSERT(0 <= id && id < kJSBuiltinsCount);
2323 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2324 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2325}
2326
2327
2328Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002329 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330}
2331
2332
2333void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002334 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335}
2336
2337
2338void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2339 visitor->VisitExternalReference(
2340 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2341}
2342
2343
2344ACCESSORS(JSValue, value, Object, kValueOffset)
2345
2346
2347JSValue* JSValue::cast(Object* obj) {
2348 ASSERT(obj->IsJSValue());
2349 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2350 return reinterpret_cast<JSValue*>(obj);
2351}
2352
2353
2354INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2355INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2356INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2357
2358
2359Code::ICTargetState Code::ic_flag() {
kasper.lund7276f142008-07-30 08:49:36 +00002360 return static_cast<ICTargetState>(READ_BYTE_FIELD(this, kICFlagOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361}
2362
2363
2364void Code::set_ic_flag(ICTargetState value) {
kasper.lund7276f142008-07-30 08:49:36 +00002365 WRITE_BYTE_FIELD(this, kICFlagOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366}
2367
2368
2369byte* Code::instruction_start() {
2370 return FIELD_ADDR(this, kHeaderSize);
2371}
2372
2373
2374int Code::body_size() {
2375 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2376}
2377
2378
2379byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002380 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381}
2382
2383
2384byte* Code::entry() {
2385 return instruction_start();
2386}
2387
2388
2389bool Code::contains(byte* pc) {
2390 return (instruction_start() <= pc) &&
2391 (pc < instruction_start() + instruction_size());
2392}
2393
2394
2395byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002396 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397}
2398
2399
2400ACCESSORS(JSArray, length, Object, kLengthOffset)
2401
2402
ager@chromium.org236ad962008-09-25 09:45:57 +00002403ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002404
2405
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002406JSRegExp::Type JSRegExp::TypeTag() {
2407 Object* data = this->data();
2408 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2409 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2410 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002411}
2412
2413
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002414int JSRegExp::CaptureCount() {
2415 switch (TypeTag()) {
2416 case ATOM:
2417 return 0;
2418 case IRREGEXP:
2419 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2420 default:
2421 UNREACHABLE();
2422 return -1;
2423 }
2424}
2425
2426
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002427JSRegExp::Flags JSRegExp::GetFlags() {
2428 ASSERT(this->data()->IsFixedArray());
2429 Object* data = this->data();
2430 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2431 return Flags(smi->value());
2432}
2433
2434
2435String* JSRegExp::Pattern() {
2436 ASSERT(this->data()->IsFixedArray());
2437 Object* data = this->data();
2438 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2439 return pattern;
2440}
2441
2442
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002443Object* JSRegExp::DataAt(int index) {
2444 ASSERT(TypeTag() != NOT_COMPILED);
2445 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002446}
2447
2448
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002449void JSRegExp::SetDataAt(int index, Object* value) {
2450 ASSERT(TypeTag() != NOT_COMPILED);
2451 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2452 FixedArray::cast(data())->set(index, value);
2453}
2454
2455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002456bool JSObject::HasFastElements() {
2457 return !elements()->IsDictionary();
2458}
2459
2460
2461bool JSObject::HasNamedInterceptor() {
2462 return map()->has_named_interceptor();
2463}
2464
2465
2466bool JSObject::HasIndexedInterceptor() {
2467 return map()->has_indexed_interceptor();
2468}
2469
2470
2471Dictionary* JSObject::property_dictionary() {
2472 ASSERT(!HasFastProperties());
2473 return Dictionary::cast(properties());
2474}
2475
2476
2477Dictionary* JSObject::element_dictionary() {
2478 ASSERT(!HasFastElements());
2479 return Dictionary::cast(elements());
2480}
2481
2482
2483bool String::HasHashCode() {
2484 return (length_field() & kHashComputedMask) != 0;
2485}
2486
2487
2488uint32_t String::Hash() {
2489 // Fast case: has hash code already been computed?
ager@chromium.org7c537e22008-10-16 08:43:32 +00002490 uint32_t field = length_field();
2491 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002492 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002493 return ComputeAndSetHash();
2494}
2495
2496
ager@chromium.org7c537e22008-10-16 08:43:32 +00002497StringHasher::StringHasher(int length)
2498 : length_(length),
2499 raw_running_hash_(0),
2500 array_index_(0),
2501 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2502 is_first_char_(true),
2503 is_valid_(true) { }
2504
2505
2506bool StringHasher::has_trivial_hash() {
2507 return length_ > String::kMaxMediumStringSize;
2508}
2509
2510
2511void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002512 // Use the Jenkins one-at-a-time hash function to update the hash
2513 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002514 raw_running_hash_ += c;
2515 raw_running_hash_ += (raw_running_hash_ << 10);
2516 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002517 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002518 if (is_array_index_) {
2519 if (c < '0' || c > '9') {
2520 is_array_index_ = false;
2521 } else {
2522 int d = c - '0';
2523 if (is_first_char_) {
2524 is_first_char_ = false;
2525 if (c == '0' && length_ > 1) {
2526 is_array_index_ = false;
2527 return;
2528 }
2529 }
2530 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2531 is_array_index_ = false;
2532 } else {
2533 array_index_ = array_index_ * 10 + d;
2534 }
2535 }
2536 }
2537}
2538
2539
2540void StringHasher::AddCharacterNoIndex(uc32 c) {
2541 ASSERT(!is_array_index());
2542 raw_running_hash_ += c;
2543 raw_running_hash_ += (raw_running_hash_ << 10);
2544 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2545}
2546
2547
2548uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002549 // Get the calculated raw hash value and do some more bit ops to distribute
2550 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002551 uint32_t result = raw_running_hash_;
2552 result += (result << 3);
2553 result ^= (result >> 11);
2554 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002555 if (result == 0) {
2556 result = 27;
2557 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002558 return result;
2559}
2560
2561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002562bool String::AsArrayIndex(uint32_t* index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002563 uint32_t field = length_field();
2564 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002565 return SlowAsArrayIndex(index);
2566}
2567
2568
2569Object* JSObject::GetPrototype() {
2570 return JSObject::cast(this)->map()->prototype();
2571}
2572
2573
2574PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2575 return GetPropertyAttributeWithReceiver(this, key);
2576}
2577
2578
2579bool JSObject::HasElement(uint32_t index) {
2580 return HasElementWithReceiver(this, index);
2581}
2582
2583
ager@chromium.orge2902be2009-06-08 12:21:35 +00002584Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
2585 // TODO(antonm): Do we want to do any shortcuts for global object?
2586 if (HasFastProperties()) {
2587 LookupResult lookup;
2588 LocalLookupRealNamedProperty(name, &lookup);
2589 if (lookup.IsValid()) {
2590 if (lookup.type() == FIELD && lookup.IsCacheable()) {
2591 return Smi::FromInt(lookup.GetFieldIndex());
2592 }
2593 } else {
2594 return Smi::FromInt(kLookupInPrototype);
2595 }
2596 }
2597
2598 return Smi::FromInt(kLookupInHolder);
2599}
2600
2601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002602bool AccessorInfo::all_can_read() {
2603 return BooleanBit::get(flag(), kAllCanReadBit);
2604}
2605
2606
2607void AccessorInfo::set_all_can_read(bool value) {
2608 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2609}
2610
2611
2612bool AccessorInfo::all_can_write() {
2613 return BooleanBit::get(flag(), kAllCanWriteBit);
2614}
2615
2616
2617void AccessorInfo::set_all_can_write(bool value) {
2618 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2619}
2620
2621
ager@chromium.org870a0b62008-11-04 11:43:05 +00002622bool AccessorInfo::prohibits_overwriting() {
2623 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2624}
2625
2626
2627void AccessorInfo::set_prohibits_overwriting(bool value) {
2628 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
2629}
2630
2631
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632PropertyAttributes AccessorInfo::property_attributes() {
2633 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
2634}
2635
2636
2637void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
2638 ASSERT(AttributesField::is_valid(attributes));
2639 int rest_value = flag()->value() & ~AttributesField::mask();
2640 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
2641}
2642
2643void Dictionary::SetEntry(int entry,
2644 Object* key,
2645 Object* value,
2646 PropertyDetails details) {
2647 ASSERT(!key->IsString() || details.index() > 0);
2648 int index = EntryToIndex(entry);
2649 WriteBarrierMode mode = GetWriteBarrierMode();
2650 set(index, key, mode);
2651 set(index+1, value, mode);
2652 fast_set(this, index+2, details.AsSmi());
2653}
2654
2655
2656void Map::ClearCodeCache() {
2657 // No write barrier is needed since empty_fixed_array is not in new space.
2658 // Please note this function is used during marking:
2659 // - MarkCompactCollector::MarkUnmarkedObject
2660 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
2661 WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());
2662}
2663
2664
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002665void JSArray::EnsureSize(int required_size) {
2666 ASSERT(HasFastElements());
2667 if (elements()->length() >= required_size) return;
2668 Expand(required_size);
2669}
2670
2671
ager@chromium.org7c537e22008-10-16 08:43:32 +00002672void JSArray::SetContent(FixedArray* storage) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002673 set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
ager@chromium.org7c537e22008-10-16 08:43:32 +00002674 set_elements(storage);
2675}
2676
2677
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002678Object* FixedArray::Copy() {
2679 if (length() == 0) return this;
2680 return Heap::CopyFixedArray(this);
2681}
2682
2683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002684#undef CAST_ACCESSOR
2685#undef INT_ACCESSORS
2686#undef SMI_ACCESSORS
2687#undef ACCESSORS
2688#undef FIELD_ADDR
2689#undef READ_FIELD
2690#undef WRITE_FIELD
2691#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002692#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002693#undef READ_MEMADDR_FIELD
2694#undef WRITE_MEMADDR_FIELD
2695#undef READ_DOUBLE_FIELD
2696#undef WRITE_DOUBLE_FIELD
2697#undef READ_INT_FIELD
2698#undef WRITE_INT_FIELD
2699#undef READ_SHORT_FIELD
2700#undef WRITE_SHORT_FIELD
2701#undef READ_BYTE_FIELD
2702#undef WRITE_BYTE_FIELD
2703
2704
2705} } // namespace v8::internal
2706
2707#endif // V8_OBJECTS_INL_H_