blob: 7a6444de525dc07e4ce2734cc09d2f611950bee1 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000056PropertyDetails PropertyDetails::AsDeleted() {
57 PropertyDetails d(DONT_ENUM, NORMAL);
58 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
59 return PropertyDetails(smi);
60}
61
62
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 ASSERT(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 }
68
69
70#define INT_ACCESSORS(holder, name, offset) \
71 int holder::name() { return READ_INT_FIELD(this, offset); } \
72 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
73
74
75#define ACCESSORS(holder, name, type, offset) \
76 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000077 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 }
81
82
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084#define SMI_ACCESSORS(holder, name, offset) \
85 int holder::name() { \
86 Object* value = READ_FIELD(this, offset); \
87 return Smi::cast(value)->value(); \
88 } \
89 void holder::set_##name(int value) { \
90 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
91 }
92
93
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000094#define BOOL_GETTER(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98
99
100#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104 void holder::set_##name(bool value) { \
105 set_##field(BooleanBit::set(field(), offset, value)); \
106 }
107
108
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000109bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
110 // There is a constraint on the object; check.
111 if (!this->IsJSObject()) return false;
112 // Fetch the constructor function of the object.
113 Object* cons_obj = JSObject::cast(this)->map()->constructor();
114 if (!cons_obj->IsJSFunction()) return false;
115 JSFunction* fun = JSFunction::cast(cons_obj);
116 // Iterate through the chain of inheriting function templates to
117 // see if the required one occurs.
118 for (Object* type = fun->shared()->function_data();
119 type->IsFunctionTemplateInfo();
120 type = FunctionTemplateInfo::cast(type)->parent_template()) {
121 if (type == expected) return true;
122 }
123 // Didn't find the required type in the inheritance chain.
124 return false;
125}
126
127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128bool Object::IsSmi() {
129 return HAS_SMI_TAG(this);
130}
131
132
133bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000134 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135}
136
137
138bool Object::IsHeapNumber() {
139 return Object::IsHeapObject()
140 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
141}
142
143
144bool Object::IsString() {
145 return Object::IsHeapObject()
146 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
147}
148
149
ager@chromium.org870a0b62008-11-04 11:43:05 +0000150bool Object::IsSymbol() {
151 if (!this->IsHeapObject()) return false;
152 uint32_t type = HeapObject::cast(this)->map()->instance_type();
153 return (type & (kIsNotStringMask | kIsSymbolMask)) ==
154 (kStringTag | kSymbolTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155}
156
157
158bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000159 if (!this->IsHeapObject()) return false;
160 uint32_t type = HeapObject::cast(this)->map()->instance_type();
161 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
162 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163}
164
165
ager@chromium.org870a0b62008-11-04 11:43:05 +0000166bool Object::IsSeqString() {
167 if (!IsString()) return false;
168 return StringShape(String::cast(this)).IsSequential();
169}
170
171
172bool Object::IsSeqAsciiString() {
173 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000174 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000175 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000176}
177
178
179bool Object::IsSeqTwoByteString() {
180 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000181 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000182 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000183}
184
185
186bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000187 if (!IsString()) return false;
188 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189}
190
191
192bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000193 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000194 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000195 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196}
197
198
199bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000200 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000201 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000202 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000203}
204
205
ager@chromium.org870a0b62008-11-04 11:43:05 +0000206StringShape::StringShape(String* str)
207 : type_(str->map()->instance_type()) {
208 set_valid();
209 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210}
211
212
ager@chromium.org870a0b62008-11-04 11:43:05 +0000213StringShape::StringShape(Map* map)
214 : type_(map->instance_type()) {
215 set_valid();
216 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220StringShape::StringShape(InstanceType t)
221 : type_(static_cast<uint32_t>(t)) {
222 set_valid();
223 ASSERT((type_ & kIsNotStringMask) == kStringTag);
224}
225
226
227bool StringShape::IsSymbol() {
228 ASSERT(valid());
229 return (type_ & kIsSymbolMask) == kSymbolTag;
230}
231
232
ager@chromium.org5ec48922009-05-05 07:25:34 +0000233bool String::IsAsciiRepresentation() {
234 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000235 if ((type & kStringRepresentationMask) == kConsStringTag &&
236 ConsString::cast(this)->second()->length() == 0) {
237 return ConsString::cast(this)->first()->IsAsciiRepresentation();
238 }
239 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000240}
241
242
ager@chromium.org5ec48922009-05-05 07:25:34 +0000243bool String::IsTwoByteRepresentation() {
244 uint32_t type = map()->instance_type();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000245 if ((type & kStringRepresentationMask) == kConsStringTag &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246 ConsString::cast(this)->second()->length() == 0) {
247 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
248 }
249 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250}
251
252
253bool StringShape::IsCons() {
254 return (type_ & kStringRepresentationMask) == kConsStringTag;
255}
256
257
ager@chromium.org870a0b62008-11-04 11:43:05 +0000258bool StringShape::IsExternal() {
259 return (type_ & kStringRepresentationMask) == kExternalStringTag;
260}
261
262
263bool StringShape::IsSequential() {
264 return (type_ & kStringRepresentationMask) == kSeqStringTag;
265}
266
267
268StringRepresentationTag StringShape::representation_tag() {
269 uint32_t tag = (type_ & kStringRepresentationMask);
270 return static_cast<StringRepresentationTag>(tag);
271}
272
273
274uint32_t StringShape::full_representation_tag() {
275 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
276}
277
278
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000279STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
280 Internals::kFullStringRepresentationMask);
281
282
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283uint32_t StringShape::size_tag() {
284 return (type_ & kStringSizeMask);
285}
286
287
288bool StringShape::IsSequentialAscii() {
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
290}
291
292
293bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
298bool StringShape::IsExternalAscii() {
299 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305}
306
307
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000308STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
309 Internals::kExternalTwoByteRepresentationTag);
310
311
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312uc32 FlatStringReader::Get(int index) {
313 ASSERT(0 <= index && index <= length_);
314 if (is_ascii_) {
315 return static_cast<const byte*>(start_)[index];
316 } else {
317 return static_cast<const uc16*>(start_)[index];
318 }
319}
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322bool Object::IsNumber() {
323 return IsSmi() || IsHeapNumber();
324}
325
326
327bool Object::IsByteArray() {
328 return Object::IsHeapObject()
329 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
330}
331
332
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000333bool Object::IsPixelArray() {
334 return Object::IsHeapObject() &&
335 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
336}
337
338
ager@chromium.org3811b432009-10-28 14:53:37 +0000339bool Object::IsExternalArray() {
340 if (!Object::IsHeapObject())
341 return false;
342 InstanceType instance_type =
343 HeapObject::cast(this)->map()->instance_type();
344 return (instance_type >= EXTERNAL_BYTE_ARRAY_TYPE &&
345 instance_type <= EXTERNAL_FLOAT_ARRAY_TYPE);
346}
347
348
349bool Object::IsExternalByteArray() {
350 return Object::IsHeapObject() &&
351 HeapObject::cast(this)->map()->instance_type() ==
352 EXTERNAL_BYTE_ARRAY_TYPE;
353}
354
355
356bool Object::IsExternalUnsignedByteArray() {
357 return Object::IsHeapObject() &&
358 HeapObject::cast(this)->map()->instance_type() ==
359 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
360}
361
362
363bool Object::IsExternalShortArray() {
364 return Object::IsHeapObject() &&
365 HeapObject::cast(this)->map()->instance_type() ==
366 EXTERNAL_SHORT_ARRAY_TYPE;
367}
368
369
370bool Object::IsExternalUnsignedShortArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalIntArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_INT_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalUnsignedIntArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalFloatArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_FLOAT_ARRAY_TYPE;
395}
396
397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398bool Object::IsFailure() {
399 return HAS_FAILURE_TAG(this);
400}
401
402
403bool Object::IsRetryAfterGC() {
404 return HAS_FAILURE_TAG(this)
405 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
406}
407
408
ager@chromium.org7c537e22008-10-16 08:43:32 +0000409bool Object::IsOutOfMemoryFailure() {
410 return HAS_FAILURE_TAG(this)
411 && Failure::cast(this)->IsOutOfMemoryException();
412}
413
414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415bool Object::IsException() {
416 return this == Failure::Exception();
417}
418
419
420bool Object::IsJSObject() {
421 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000422 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423}
424
425
ager@chromium.org32912102009-01-16 10:38:43 +0000426bool Object::IsJSContextExtensionObject() {
427 return IsHeapObject()
428 && (HeapObject::cast(this)->map()->instance_type() ==
429 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
430}
431
432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433bool Object::IsMap() {
434 return Object::IsHeapObject()
435 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
436}
437
438
439bool Object::IsFixedArray() {
440 return Object::IsHeapObject()
441 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
442}
443
444
445bool Object::IsDescriptorArray() {
446 return IsFixedArray();
447}
448
449
450bool Object::IsContext() {
451 return Object::IsHeapObject()
452 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000453 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 HeapObject::cast(this)->map() == Heap::global_context_map());
455}
456
457
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000458bool Object::IsCatchContext() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::catch_context_map();
461}
462
463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464bool Object::IsGlobalContext() {
465 return Object::IsHeapObject()
466 && HeapObject::cast(this)->map() == Heap::global_context_map();
467}
468
469
470bool Object::IsJSFunction() {
471 return Object::IsHeapObject()
472 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
473}
474
475
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000476template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 return obj->IsJSFunction();
478}
479
480
481bool Object::IsCode() {
482 return Object::IsHeapObject()
483 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
484}
485
486
487bool Object::IsOddball() {
488 return Object::IsHeapObject()
489 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
490}
491
492
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000493bool Object::IsJSGlobalPropertyCell() {
494 return Object::IsHeapObject()
495 && HeapObject::cast(this)->map()->instance_type()
496 == JS_GLOBAL_PROPERTY_CELL_TYPE;
497}
498
499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500bool Object::IsSharedFunctionInfo() {
501 return Object::IsHeapObject() &&
502 (HeapObject::cast(this)->map()->instance_type() ==
503 SHARED_FUNCTION_INFO_TYPE);
504}
505
506
507bool Object::IsJSValue() {
508 return Object::IsHeapObject()
509 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
510}
511
512
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000513bool Object::IsStringWrapper() {
514 return IsJSValue() && JSValue::cast(this)->value()->IsString();
515}
516
517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000518bool Object::IsProxy() {
519 return Object::IsHeapObject()
520 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
521}
522
523
524bool Object::IsBoolean() {
525 return IsTrue() || IsFalse();
526}
527
528
529bool Object::IsJSArray() {
530 return Object::IsHeapObject()
531 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
532}
533
534
ager@chromium.org236ad962008-09-25 09:45:57 +0000535bool Object::IsJSRegExp() {
536 return Object::IsHeapObject()
537 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
538}
539
540
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000541template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 return obj->IsJSArray();
543}
544
545
546bool Object::IsHashTable() {
547 return Object::IsHeapObject()
548 && HeapObject::cast(this)->map() == Heap::hash_table_map();
549}
550
551
552bool Object::IsDictionary() {
553 return IsHashTable() && this != Heap::symbol_table();
554}
555
556
557bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000558 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000559}
560
561
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000562bool Object::IsCompilationCacheTable() {
563 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000564}
565
566
ager@chromium.org236ad962008-09-25 09:45:57 +0000567bool Object::IsMapCache() {
568 return IsHashTable();
569}
570
571
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000572bool Object::IsPrimitive() {
573 return IsOddball() || IsNumber() || IsString();
574}
575
576
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000577bool Object::IsJSGlobalProxy() {
578 bool result = IsHeapObject() &&
579 (HeapObject::cast(this)->map()->instance_type() ==
580 JS_GLOBAL_PROXY_TYPE);
581 ASSERT(!result || IsAccessCheckNeeded());
582 return result;
583}
584
585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000587 if (!IsHeapObject()) return false;
588
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000589 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000590 return type == JS_GLOBAL_OBJECT_TYPE ||
591 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000592}
593
594
595bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596 return IsHeapObject() &&
597 (HeapObject::cast(this)->map()->instance_type() ==
598 JS_GLOBAL_OBJECT_TYPE);
599}
600
601
602bool Object::IsJSBuiltinsObject() {
603 return IsHeapObject() &&
604 (HeapObject::cast(this)->map()->instance_type() ==
605 JS_BUILTINS_OBJECT_TYPE);
606}
607
608
609bool Object::IsUndetectableObject() {
610 return IsHeapObject()
611 && HeapObject::cast(this)->map()->is_undetectable();
612}
613
614
615bool Object::IsAccessCheckNeeded() {
616 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000617 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618}
619
620
621bool Object::IsStruct() {
622 if (!IsHeapObject()) return false;
623 switch (HeapObject::cast(this)->map()->instance_type()) {
624#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
625 STRUCT_LIST(MAKE_STRUCT_CASE)
626#undef MAKE_STRUCT_CASE
627 default: return false;
628 }
629}
630
631
632#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
633 bool Object::Is##Name() { \
634 return Object::IsHeapObject() \
635 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
636 }
637 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
638#undef MAKE_STRUCT_PREDICATE
639
640
641bool Object::IsUndefined() {
642 return this == Heap::undefined_value();
643}
644
645
646bool Object::IsTheHole() {
647 return this == Heap::the_hole_value();
648}
649
650
651bool Object::IsNull() {
652 return this == Heap::null_value();
653}
654
655
656bool Object::IsTrue() {
657 return this == Heap::true_value();
658}
659
660
661bool Object::IsFalse() {
662 return this == Heap::false_value();
663}
664
665
666double Object::Number() {
667 ASSERT(IsNumber());
668 return IsSmi()
669 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
670 : reinterpret_cast<HeapNumber*>(this)->value();
671}
672
673
674
675Object* Object::ToSmi() {
676 if (IsSmi()) return this;
677 if (IsHeapNumber()) {
678 double value = HeapNumber::cast(this)->value();
679 int int_value = FastD2I(value);
680 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
681 return Smi::FromInt(int_value);
682 }
683 }
684 return Failure::Exception();
685}
686
687
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000688bool Object::HasSpecificClassOf(String* name) {
689 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
690}
691
692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000693Object* Object::GetElement(uint32_t index) {
694 return GetElementWithReceiver(this, index);
695}
696
697
698Object* Object::GetProperty(String* key) {
699 PropertyAttributes attributes;
700 return GetPropertyWithReceiver(this, key, &attributes);
701}
702
703
704Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
705 return GetPropertyWithReceiver(this, key, attributes);
706}
707
708
709#define FIELD_ADDR(p, offset) \
710 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
711
712#define READ_FIELD(p, offset) \
713 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
714
715#define WRITE_FIELD(p, offset, value) \
716 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000718
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000719#define WRITE_BARRIER(object, offset) \
720 Heap::RecordWrite(object->address(), offset);
721
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000722// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000723// write due to the assert validating the written value.
724#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
725 if (mode == UPDATE_WRITE_BARRIER) { \
726 Heap::RecordWrite(object->address(), offset); \
727 } else { \
728 ASSERT(mode == SKIP_WRITE_BARRIER); \
729 ASSERT(Heap::InNewSpace(object) || \
730 !Heap::InNewSpace(READ_FIELD(object, offset))); \
731 }
732
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733#define READ_DOUBLE_FIELD(p, offset) \
734 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
735
736#define WRITE_DOUBLE_FIELD(p, offset, value) \
737 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
738
739#define READ_INT_FIELD(p, offset) \
740 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
741
742#define WRITE_INT_FIELD(p, offset, value) \
743 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
744
ager@chromium.org3e875802009-06-29 08:26:34 +0000745#define READ_INTPTR_FIELD(p, offset) \
746 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
747
748#define WRITE_INTPTR_FIELD(p, offset, value) \
749 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
750
ager@chromium.org7c537e22008-10-16 08:43:32 +0000751#define READ_UINT32_FIELD(p, offset) \
752 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
753
754#define WRITE_UINT32_FIELD(p, offset, value) \
755 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757#define READ_SHORT_FIELD(p, offset) \
758 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
759
760#define WRITE_SHORT_FIELD(p, offset, value) \
761 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
762
763#define READ_BYTE_FIELD(p, offset) \
764 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
765
766#define WRITE_BYTE_FIELD(p, offset, value) \
767 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
768
769
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000770Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
771 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
775int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000776 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780Smi* Smi::FromInt(int value) {
781 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000782 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000783 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000784 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000785 return reinterpret_cast<Smi*>(tagged_value);
786}
787
788
789Smi* Smi::FromIntptr(intptr_t value) {
790 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000791 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
792 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000793}
794
795
796Failure::Type Failure::type() const {
797 return static_cast<Type>(value() & kFailureTypeTagMask);
798}
799
800
801bool Failure::IsInternalError() const {
802 return type() == INTERNAL_ERROR;
803}
804
805
806bool Failure::IsOutOfMemoryException() const {
807 return type() == OUT_OF_MEMORY_EXCEPTION;
808}
809
810
811int Failure::requested() const {
812 const int kShiftBits =
813 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
814 STATIC_ASSERT(kShiftBits >= 0);
815 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000816 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817}
818
819
820AllocationSpace Failure::allocation_space() const {
821 ASSERT_EQ(RETRY_AFTER_GC, type());
822 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
823 & kSpaceTagMask);
824}
825
826
827Failure* Failure::InternalError() {
828 return Construct(INTERNAL_ERROR);
829}
830
831
832Failure* Failure::Exception() {
833 return Construct(EXCEPTION);
834}
835
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000837Failure* Failure::OutOfMemoryException() {
838 return Construct(OUT_OF_MEMORY_EXCEPTION);
839}
840
841
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000842intptr_t Failure::value() const {
843 return reinterpret_cast<intptr_t>(this) >> kFailureTagSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000844}
845
846
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000847Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000848 // Assert that the space encoding fits in the three bytes allotted for it.
849 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000850 intptr_t requested = requested_bytes >> kObjectAlignmentBits;
851 int tag_bits = kSpaceTagSize + kFailureTypeTagSize;
852 if (((requested << tag_bits) >> tag_bits) != requested) {
853 // No room for entire requested size in the bits. Round down to
854 // maximally representable size.
855 requested = static_cast<intptr_t>(
856 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
857 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000858 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000859 return Construct(RETRY_AFTER_GC, value);
860}
861
862
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000863Failure* Failure::Construct(Type type, intptr_t value) {
864 intptr_t info = (static_cast<intptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000865 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000866 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867}
868
869
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000870bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000871#ifdef DEBUG
872 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
873#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874
875#ifdef V8_TARGET_ARCH_X64
876 // To be representable as a long smi, the value must be a 32-bit integer.
877 bool result = (value == static_cast<int32_t>(value));
878#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879 // To be representable as an tagged small integer, the two
880 // most-significant bits of 'value' must be either 00 or 11 due to
881 // sign-extension. To check this we add 01 to the two
882 // most-significant bits, and check if the most-significant bit is 0
883 //
884 // CAUTION: The original code below:
885 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
886 // may lead to incorrect results according to the C language spec, and
887 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
888 // compiler may produce undefined results in case of signed integer
889 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000890 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000891#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000892 ASSERT(result == in_range);
893 return result;
894}
895
896
kasper.lund7276f142008-07-30 08:49:36 +0000897MapWord MapWord::FromMap(Map* map) {
898 return MapWord(reinterpret_cast<uintptr_t>(map));
899}
900
901
902Map* MapWord::ToMap() {
903 return reinterpret_cast<Map*>(value_);
904}
905
906
907bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000908 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000909}
910
911
912MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000913 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
914 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000915}
916
917
918HeapObject* MapWord::ToForwardingAddress() {
919 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000920 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000921}
922
923
ager@chromium.org3811b432009-10-28 14:53:37 +0000924bool MapWord::IsSerializationAddress() {
925 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
926}
927
928
929MapWord MapWord::FromSerializationAddress(int raw) {
930 // When the map word is being used as a serialization address we Smi-encode
931 // the serialization address (which is always a smallish positive integer).
932 return MapWord(reinterpret_cast<uintptr_t>(Smi::FromInt(raw)));
933}
934
935
936int MapWord::ToSerializationAddress() {
937 // When the map word is being used as a serialization address we treat the
938 // map word as a Smi and get the small integer that it encodes.
939 return reinterpret_cast<Smi*>(value_)->value();
940}
941
942
kasper.lund7276f142008-07-30 08:49:36 +0000943bool MapWord::IsMarked() {
944 return (value_ & kMarkingMask) == 0;
945}
946
947
948void MapWord::SetMark() {
949 value_ &= ~kMarkingMask;
950}
951
952
953void MapWord::ClearMark() {
954 value_ |= kMarkingMask;
955}
956
957
958bool MapWord::IsOverflowed() {
959 return (value_ & kOverflowMask) != 0;
960}
961
962
963void MapWord::SetOverflow() {
964 value_ |= kOverflowMask;
965}
966
967
968void MapWord::ClearOverflow() {
969 value_ &= ~kOverflowMask;
970}
971
972
973MapWord MapWord::EncodeAddress(Address map_address, int offset) {
974 // Offset is the distance in live bytes from the first live object in the
975 // same page. The offset between two objects in the same page should not
976 // exceed the object area size of a page.
977 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
978
979 int compact_offset = offset >> kObjectAlignmentBits;
980 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
981
982 Page* map_page = Page::FromAddress(map_address);
983 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
984
985 int map_page_offset =
986 map_page->Offset(map_address) >> kObjectAlignmentBits;
987
988 uintptr_t encoding =
989 (compact_offset << kForwardingOffsetShift) |
990 (map_page_offset << kMapPageOffsetShift) |
991 (map_page->mc_page_index << kMapPageIndexShift);
992 return MapWord(encoding);
993}
994
995
996Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000997 int map_page_index =
998 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +0000999 ASSERT_MAP_PAGE_INDEX(map_page_index);
1000
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001001 int map_page_offset = static_cast<int>(
kasper.lund7276f142008-07-30 08:49:36 +00001002 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift)
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001003 << kObjectAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001004
1005 return (map_space->PageAddress(map_page_index) + map_page_offset);
1006}
1007
1008
1009int MapWord::DecodeOffset() {
1010 // The offset field is represented in the kForwardingOffsetBits
1011 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001012 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1013 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1014 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001015}
1016
1017
1018MapWord MapWord::FromEncodedAddress(Address address) {
1019 return MapWord(reinterpret_cast<uintptr_t>(address));
1020}
1021
1022
1023Address MapWord::ToEncodedAddress() {
1024 return reinterpret_cast<Address>(value_);
1025}
1026
1027
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001028#ifdef DEBUG
1029void HeapObject::VerifyObjectField(int offset) {
1030 VerifyPointer(READ_FIELD(this, offset));
1031}
1032#endif
1033
1034
1035Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001036 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037}
1038
1039
1040void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001041 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042}
1043
1044
kasper.lund7276f142008-07-30 08:49:36 +00001045MapWord HeapObject::map_word() {
1046 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1047}
1048
1049
1050void HeapObject::set_map_word(MapWord map_word) {
1051 // WRITE_FIELD does not update the remembered set, but there is no need
1052 // here.
1053 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1054}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055
1056
1057HeapObject* HeapObject::FromAddress(Address address) {
1058 ASSERT_TAG_ALIGNED(address);
1059 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1060}
1061
1062
1063Address HeapObject::address() {
1064 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1065}
1066
1067
1068int HeapObject::Size() {
1069 return SizeFromMap(map());
1070}
1071
1072
1073void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1074 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1075 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1076}
1077
1078
1079void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1080 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1081}
1082
1083
kasper.lund7276f142008-07-30 08:49:36 +00001084bool HeapObject::IsMarked() {
1085 return map_word().IsMarked();
1086}
1087
1088
1089void HeapObject::SetMark() {
1090 ASSERT(!IsMarked());
1091 MapWord first_word = map_word();
1092 first_word.SetMark();
1093 set_map_word(first_word);
1094}
1095
1096
1097void HeapObject::ClearMark() {
1098 ASSERT(IsMarked());
1099 MapWord first_word = map_word();
1100 first_word.ClearMark();
1101 set_map_word(first_word);
1102}
1103
1104
1105bool HeapObject::IsOverflowed() {
1106 return map_word().IsOverflowed();
1107}
1108
1109
1110void HeapObject::SetOverflow() {
1111 MapWord first_word = map_word();
1112 first_word.SetOverflow();
1113 set_map_word(first_word);
1114}
1115
1116
1117void HeapObject::ClearOverflow() {
1118 ASSERT(IsOverflowed());
1119 MapWord first_word = map_word();
1120 first_word.ClearOverflow();
1121 set_map_word(first_word);
1122}
1123
1124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125double HeapNumber::value() {
1126 return READ_DOUBLE_FIELD(this, kValueOffset);
1127}
1128
1129
1130void HeapNumber::set_value(double value) {
1131 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1132}
1133
1134
1135ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001136
1137
1138Array* JSObject::elements() {
1139 Object* array = READ_FIELD(this, kElementsOffset);
1140 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001141 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1142 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001143 return reinterpret_cast<Array*>(array);
1144}
1145
1146
1147void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1148 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001149 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1150 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001151 WRITE_FIELD(this, kElementsOffset, value);
1152 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1153}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154
1155
1156void JSObject::initialize_properties() {
1157 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1158 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1159}
1160
1161
1162void JSObject::initialize_elements() {
1163 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1164 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1165}
1166
1167
1168ACCESSORS(Oddball, to_string, String, kToStringOffset)
1169ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1170
1171
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001172Object* JSGlobalPropertyCell::value() {
1173 return READ_FIELD(this, kValueOffset);
1174}
1175
1176
1177void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1178 // The write barrier is not used for global property cells.
1179 ASSERT(!val->IsJSGlobalPropertyCell());
1180 WRITE_FIELD(this, kValueOffset, val);
1181}
1182
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001183
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001184int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001185 InstanceType type = map()->instance_type();
1186 // Check for the most common kind of JavaScript object before
1187 // falling into the generic switch. This speeds up the internal
1188 // field operations considerably on average.
1189 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1190 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001191 case JS_GLOBAL_PROXY_TYPE:
1192 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193 case JS_GLOBAL_OBJECT_TYPE:
1194 return JSGlobalObject::kSize;
1195 case JS_BUILTINS_OBJECT_TYPE:
1196 return JSBuiltinsObject::kSize;
1197 case JS_FUNCTION_TYPE:
1198 return JSFunction::kSize;
1199 case JS_VALUE_TYPE:
1200 return JSValue::kSize;
1201 case JS_ARRAY_TYPE:
1202 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001203 case JS_REGEXP_TYPE:
1204 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001205 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001206 return JSObject::kHeaderSize;
1207 default:
1208 UNREACHABLE();
1209 return 0;
1210 }
1211}
1212
1213
1214int JSObject::GetInternalFieldCount() {
1215 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001216 // Make sure to adjust for the number of in-object properties. These
1217 // properties do contribute to the size, but are not internal fields.
1218 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1219 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220}
1221
1222
1223Object* JSObject::GetInternalField(int index) {
1224 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001225 // Internal objects do follow immediately after the header, whereas in-object
1226 // properties are at the end of the object. Therefore there is no need
1227 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001228 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1229}
1230
1231
1232void JSObject::SetInternalField(int index, Object* value) {
1233 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001234 // Internal objects do follow immediately after the header, whereas in-object
1235 // properties are at the end of the object. Therefore there is no need
1236 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237 int offset = GetHeaderSize() + (kPointerSize * index);
1238 WRITE_FIELD(this, offset, value);
1239 WRITE_BARRIER(this, offset);
1240}
1241
1242
ager@chromium.org7c537e22008-10-16 08:43:32 +00001243// Access fast-case object properties at index. The use of these routines
1244// is needed to correctly distinguish between properties stored in-object and
1245// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001246Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001247 // Adjust for the number of properties stored in the object.
1248 index -= map()->inobject_properties();
1249 if (index < 0) {
1250 int offset = map()->instance_size() + (index * kPointerSize);
1251 return READ_FIELD(this, offset);
1252 } else {
1253 ASSERT(index < properties()->length());
1254 return properties()->get(index);
1255 }
1256}
1257
1258
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001259Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001260 // Adjust for the number of properties stored in the object.
1261 index -= map()->inobject_properties();
1262 if (index < 0) {
1263 int offset = map()->instance_size() + (index * kPointerSize);
1264 WRITE_FIELD(this, offset, value);
1265 WRITE_BARRIER(this, offset);
1266 } else {
1267 ASSERT(index < properties()->length());
1268 properties()->set(index, value);
1269 }
1270 return value;
1271}
1272
1273
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001274Object* JSObject::InObjectPropertyAt(int index) {
1275 // Adjust for the number of properties stored in the object.
1276 index -= map()->inobject_properties();
1277 ASSERT(index < 0);
1278 int offset = map()->instance_size() + (index * kPointerSize);
1279 return READ_FIELD(this, offset);
1280}
1281
1282
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001283Object* JSObject::InObjectPropertyAtPut(int index,
1284 Object* value,
1285 WriteBarrierMode mode) {
1286 // Adjust for the number of properties stored in the object.
1287 index -= map()->inobject_properties();
1288 ASSERT(index < 0);
1289 int offset = map()->instance_size() + (index * kPointerSize);
1290 WRITE_FIELD(this, offset, value);
1291 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1292 return value;
1293}
1294
1295
1296
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001297void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001298 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001299 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001300 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301 }
1302}
1303
1304
1305void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001306 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001307 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001308 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309 }
1310}
1311
1312
1313bool JSObject::HasFastProperties() {
1314 return !properties()->IsDictionary();
1315}
1316
1317
1318bool Array::IndexFromObject(Object* object, uint32_t* index) {
1319 if (object->IsSmi()) {
1320 int value = Smi::cast(object)->value();
1321 if (value < 0) return false;
1322 *index = value;
1323 return true;
1324 }
1325 if (object->IsHeapNumber()) {
1326 double value = HeapNumber::cast(object)->value();
1327 uint32_t uint_value = static_cast<uint32_t>(value);
1328 if (value == static_cast<double>(uint_value)) {
1329 *index = uint_value;
1330 return true;
1331 }
1332 }
1333 return false;
1334}
1335
1336
1337bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1338 if (!this->IsJSValue()) return false;
1339
1340 JSValue* js_value = JSValue::cast(this);
1341 if (!js_value->value()->IsString()) return false;
1342
1343 String* str = String::cast(js_value->value());
1344 if (index >= (uint32_t)str->length()) return false;
1345
1346 return true;
1347}
1348
1349
1350Object* FixedArray::get(int index) {
1351 ASSERT(index >= 0 && index < this->length());
1352 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1353}
1354
1355
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001356void FixedArray::set(int index, Smi* value) {
1357 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1358 int offset = kHeaderSize + index * kPointerSize;
1359 WRITE_FIELD(this, offset, value);
1360}
1361
1362
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001363void FixedArray::set(int index, Object* value) {
1364 ASSERT(index >= 0 && index < this->length());
1365 int offset = kHeaderSize + index * kPointerSize;
1366 WRITE_FIELD(this, offset, value);
1367 WRITE_BARRIER(this, offset);
1368}
1369
1370
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001371WriteBarrierMode HeapObject::GetWriteBarrierMode() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1373 return UPDATE_WRITE_BARRIER;
1374}
1375
1376
1377void FixedArray::set(int index,
1378 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001379 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 ASSERT(index >= 0 && index < this->length());
1381 int offset = kHeaderSize + index * kPointerSize;
1382 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384}
1385
1386
1387void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1388 ASSERT(index >= 0 && index < array->length());
1389 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1390}
1391
1392
1393void FixedArray::set_undefined(int index) {
1394 ASSERT(index >= 0 && index < this->length());
1395 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1396 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1397 Heap::undefined_value());
1398}
1399
1400
ager@chromium.org236ad962008-09-25 09:45:57 +00001401void FixedArray::set_null(int index) {
1402 ASSERT(index >= 0 && index < this->length());
1403 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1404 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1405}
1406
1407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408void FixedArray::set_the_hole(int index) {
1409 ASSERT(index >= 0 && index < this->length());
1410 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1411 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1412}
1413
1414
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001415bool DescriptorArray::IsEmpty() {
1416 ASSERT(this == Heap::empty_descriptor_array() ||
1417 this->length() > 2);
1418 return this == Heap::empty_descriptor_array();
1419}
1420
1421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1423 Object* tmp = array->get(first);
1424 fast_set(array, first, array->get(second));
1425 fast_set(array, second, tmp);
1426}
1427
1428
1429int DescriptorArray::Search(String* name) {
1430 SLOW_ASSERT(IsSortedNoDuplicates());
1431
1432 // Check for empty descriptor array.
1433 int nof = number_of_descriptors();
1434 if (nof == 0) return kNotFound;
1435
1436 // Fast case: do linear search for small arrays.
1437 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001438 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001439 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 }
1441
1442 // Slow case: perform binary search.
1443 return BinarySearch(name, 0, nof - 1);
1444}
1445
1446
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447String* DescriptorArray::GetKey(int descriptor_number) {
1448 ASSERT(descriptor_number < number_of_descriptors());
1449 return String::cast(get(ToKeyIndex(descriptor_number)));
1450}
1451
1452
1453Object* DescriptorArray::GetValue(int descriptor_number) {
1454 ASSERT(descriptor_number < number_of_descriptors());
1455 return GetContentArray()->get(ToValueIndex(descriptor_number));
1456}
1457
1458
1459Smi* DescriptorArray::GetDetails(int descriptor_number) {
1460 ASSERT(descriptor_number < number_of_descriptors());
1461 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1462}
1463
1464
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001465PropertyType DescriptorArray::GetType(int descriptor_number) {
1466 ASSERT(descriptor_number < number_of_descriptors());
1467 return PropertyDetails(GetDetails(descriptor_number)).type();
1468}
1469
1470
1471int DescriptorArray::GetFieldIndex(int descriptor_number) {
1472 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1473}
1474
1475
1476JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1477 return JSFunction::cast(GetValue(descriptor_number));
1478}
1479
1480
1481Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1482 ASSERT(GetType(descriptor_number) == CALLBACKS);
1483 return GetValue(descriptor_number);
1484}
1485
1486
1487AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1488 ASSERT(GetType(descriptor_number) == CALLBACKS);
1489 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1490 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1491}
1492
1493
1494bool DescriptorArray::IsProperty(int descriptor_number) {
1495 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1496}
1497
1498
1499bool DescriptorArray::IsTransition(int descriptor_number) {
1500 PropertyType t = GetType(descriptor_number);
1501 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1502}
1503
1504
1505bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1506 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1507}
1508
1509
1510bool DescriptorArray::IsDontEnum(int descriptor_number) {
1511 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1512}
1513
1514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001515void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1516 desc->Init(GetKey(descriptor_number),
1517 GetValue(descriptor_number),
1518 GetDetails(descriptor_number));
1519}
1520
1521
1522void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1523 // Range check.
1524 ASSERT(descriptor_number < number_of_descriptors());
1525
1526 // Make sure non of the elements in desc are in new space.
1527 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1528 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1529
1530 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1531 FixedArray* content_array = GetContentArray();
1532 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1533 fast_set(content_array, ToDetailsIndex(descriptor_number),
1534 desc->GetDetails().AsSmi());
1535}
1536
1537
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001538void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1539 Descriptor desc;
1540 src->Get(src_index, &desc);
1541 Set(index, &desc);
1542}
1543
1544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545void DescriptorArray::Swap(int first, int second) {
1546 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1547 FixedArray* content_array = GetContentArray();
1548 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1549 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1550}
1551
1552
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001553bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001554 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555 if (!max_index_object->IsSmi()) return false;
1556 return 0 !=
1557 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1558}
1559
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001560uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001562 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001563 if (!max_index_object->IsSmi()) return 0;
1564 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1565 return value >> kRequiresSlowElementsTagSize;
1566}
1567
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001568void NumberDictionary::set_requires_slow_elements() {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001569 set(kMaxNumberKeyIndex,
1570 Smi::FromInt(kRequiresSlowElementsMask),
1571 SKIP_WRITE_BARRIER);
1572}
1573
1574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575// ------------------------------------
1576// Cast operations
1577
1578
1579CAST_ACCESSOR(FixedArray)
1580CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001581CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001582CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001583CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001584CAST_ACCESSOR(String)
1585CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001586CAST_ACCESSOR(SeqAsciiString)
1587CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001588CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589CAST_ACCESSOR(ExternalString)
1590CAST_ACCESSOR(ExternalAsciiString)
1591CAST_ACCESSOR(ExternalTwoByteString)
1592CAST_ACCESSOR(JSObject)
1593CAST_ACCESSOR(Smi)
1594CAST_ACCESSOR(Failure)
1595CAST_ACCESSOR(HeapObject)
1596CAST_ACCESSOR(HeapNumber)
1597CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001598CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599CAST_ACCESSOR(SharedFunctionInfo)
1600CAST_ACCESSOR(Map)
1601CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001602CAST_ACCESSOR(GlobalObject)
1603CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604CAST_ACCESSOR(JSGlobalObject)
1605CAST_ACCESSOR(JSBuiltinsObject)
1606CAST_ACCESSOR(Code)
1607CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001608CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609CAST_ACCESSOR(Proxy)
1610CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001611CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001612CAST_ACCESSOR(ExternalArray)
1613CAST_ACCESSOR(ExternalByteArray)
1614CAST_ACCESSOR(ExternalUnsignedByteArray)
1615CAST_ACCESSOR(ExternalShortArray)
1616CAST_ACCESSOR(ExternalUnsignedShortArray)
1617CAST_ACCESSOR(ExternalIntArray)
1618CAST_ACCESSOR(ExternalUnsignedIntArray)
1619CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620CAST_ACCESSOR(Struct)
1621
1622
1623#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1624 STRUCT_LIST(MAKE_STRUCT_CAST)
1625#undef MAKE_STRUCT_CAST
1626
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001627
1628template <typename Shape, typename Key>
1629HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001630 ASSERT(obj->IsHashTable());
1631 return reinterpret_cast<HashTable*>(obj);
1632}
1633
1634
1635INT_ACCESSORS(Array, length, kLengthOffset)
1636
1637
1638bool String::Equals(String* other) {
1639 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001640 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1641 return false;
1642 }
1643 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644}
1645
1646
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001647int String::length() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001648 uint32_t len = READ_INT_FIELD(this, kLengthOffset);
1649
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001650 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1651 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1652 ASSERT(kLongStringTag == 0);
1653
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001654 return len >> (StringShape(this).size_tag() + kLongLengthShift);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655}
1656
1657
1658void String::set_length(int value) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001659 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1660 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1661 ASSERT(kLongStringTag == 0);
1662
1663 WRITE_INT_FIELD(this,
1664 kLengthOffset,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001665 value << (StringShape(this).size_tag() + kLongLengthShift));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666}
1667
1668
ager@chromium.org7c537e22008-10-16 08:43:32 +00001669uint32_t String::length_field() {
1670 return READ_UINT32_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671}
1672
1673
ager@chromium.org7c537e22008-10-16 08:43:32 +00001674void String::set_length_field(uint32_t value) {
1675 WRITE_UINT32_FIELD(this, kLengthOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001676}
1677
1678
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001679Object* String::TryFlattenIfNotFlat() {
ager@chromium.org236ad962008-09-25 09:45:57 +00001680 // We don't need to flatten strings that are already flat. Since this code
1681 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001682 if (!IsFlat()) {
1683 return TryFlatten();
ager@chromium.org236ad962008-09-25 09:45:57 +00001684 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001685 return this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001686}
1687
1688
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001689uint16_t String::Get(int index) {
1690 ASSERT(index >= 0 && index < length());
1691 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001692 case kSeqStringTag | kAsciiStringTag:
1693 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1694 case kSeqStringTag | kTwoByteStringTag:
1695 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1696 case kConsStringTag | kAsciiStringTag:
1697 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001699 case kExternalStringTag | kAsciiStringTag:
1700 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1701 case kExternalStringTag | kTwoByteStringTag:
1702 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703 default:
1704 break;
1705 }
1706
1707 UNREACHABLE();
1708 return 0;
1709}
1710
1711
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001712void String::Set(int index, uint16_t value) {
1713 ASSERT(index >= 0 && index < length());
1714 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715
ager@chromium.org5ec48922009-05-05 07:25:34 +00001716 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001717 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1718 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001719}
1720
1721
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001722bool String::IsFlat() {
1723 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001724 case kConsStringTag: {
1725 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001726 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001727 return second->length() == 0;
1728 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001729 default:
1730 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731 }
1732}
1733
1734
ager@chromium.org7c537e22008-10-16 08:43:32 +00001735uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736 ASSERT(index >= 0 && index < length());
1737 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1738}
1739
1740
ager@chromium.org7c537e22008-10-16 08:43:32 +00001741void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1743 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1744 static_cast<byte>(value));
1745}
1746
1747
ager@chromium.org7c537e22008-10-16 08:43:32 +00001748Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749 return FIELD_ADDR(this, kHeaderSize);
1750}
1751
1752
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001753char* SeqAsciiString::GetChars() {
1754 return reinterpret_cast<char*>(GetCharsAddress());
1755}
1756
1757
ager@chromium.org7c537e22008-10-16 08:43:32 +00001758Address SeqTwoByteString::GetCharsAddress() {
1759 return FIELD_ADDR(this, kHeaderSize);
1760}
1761
1762
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001763uc16* SeqTwoByteString::GetChars() {
1764 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1765}
1766
1767
ager@chromium.org7c537e22008-10-16 08:43:32 +00001768uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769 ASSERT(index >= 0 && index < length());
1770 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1771}
1772
1773
ager@chromium.org7c537e22008-10-16 08:43:32 +00001774void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001775 ASSERT(index >= 0 && index < length());
1776 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1777}
1778
1779
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001780int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1782
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001783 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1784 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1785 ASSERT(kLongStringTag == 0);
1786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 // Use the map (and not 'this') to compute the size tag, since
1788 // TwoByteStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001789 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001790
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791 return SizeFor(length);
1792}
1793
1794
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001795int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1797
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001798 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1799 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1800 ASSERT(kLongStringTag == 0);
1801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001802 // Use the map (and not 'this') to compute the size tag, since
1803 // AsciiStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001804 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805
1806 return SizeFor(length);
1807}
1808
1809
ager@chromium.org870a0b62008-11-04 11:43:05 +00001810String* ConsString::first() {
1811 return String::cast(READ_FIELD(this, kFirstOffset));
1812}
1813
1814
1815Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 return READ_FIELD(this, kFirstOffset);
1817}
1818
1819
ager@chromium.org870a0b62008-11-04 11:43:05 +00001820void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001821 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001822 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823}
1824
1825
ager@chromium.org870a0b62008-11-04 11:43:05 +00001826String* ConsString::second() {
1827 return String::cast(READ_FIELD(this, kSecondOffset));
1828}
1829
1830
1831Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001832 return READ_FIELD(this, kSecondOffset);
1833}
1834
1835
ager@chromium.org870a0b62008-11-04 11:43:05 +00001836void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001838 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839}
1840
1841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001842ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1843 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1844}
1845
1846
1847void ExternalAsciiString::set_resource(
1848 ExternalAsciiString::Resource* resource) {
1849 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1850}
1851
1852
ager@chromium.org6f10e412009-02-13 10:11:16 +00001853Map* ExternalAsciiString::StringMap(int length) {
1854 Map* map;
1855 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001856 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001857 map = Heap::short_external_ascii_string_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001858 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001859 map = Heap::medium_external_ascii_string_map();
1860 } else {
1861 map = Heap::long_external_ascii_string_map();
1862 }
1863 return map;
1864}
1865
1866
1867Map* ExternalAsciiString::SymbolMap(int length) {
1868 Map* map;
1869 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001870 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001871 map = Heap::short_external_ascii_symbol_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001872 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001873 map = Heap::medium_external_ascii_symbol_map();
1874 } else {
1875 map = Heap::long_external_ascii_symbol_map();
1876 }
1877 return map;
1878}
1879
1880
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1882 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1883}
1884
1885
1886void ExternalTwoByteString::set_resource(
1887 ExternalTwoByteString::Resource* resource) {
1888 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1889}
1890
1891
ager@chromium.org6f10e412009-02-13 10:11:16 +00001892Map* ExternalTwoByteString::StringMap(int length) {
1893 Map* map;
1894 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001895 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001896 map = Heap::short_external_string_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001897 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001898 map = Heap::medium_external_string_map();
1899 } else {
1900 map = Heap::long_external_string_map();
1901 }
1902 return map;
1903}
1904
1905
1906Map* ExternalTwoByteString::SymbolMap(int length) {
1907 Map* map;
1908 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001909 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001910 map = Heap::short_external_symbol_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001911 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001912 map = Heap::medium_external_symbol_map();
1913 } else {
1914 map = Heap::long_external_symbol_map();
1915 }
1916 return map;
1917}
1918
1919
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920byte ByteArray::get(int index) {
1921 ASSERT(index >= 0 && index < this->length());
1922 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1923}
1924
1925
1926void ByteArray::set(int index, byte value) {
1927 ASSERT(index >= 0 && index < this->length());
1928 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1929}
1930
1931
1932int ByteArray::get_int(int index) {
1933 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1934 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1935}
1936
1937
1938ByteArray* ByteArray::FromDataStartAddress(Address address) {
1939 ASSERT_TAG_ALIGNED(address);
1940 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1941}
1942
1943
1944Address ByteArray::GetDataStartAddress() {
1945 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1946}
1947
1948
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001949uint8_t* PixelArray::external_pointer() {
1950 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1951 return reinterpret_cast<uint8_t*>(ptr);
1952}
1953
1954
1955void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1956 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1957 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1958}
1959
1960
1961uint8_t PixelArray::get(int index) {
1962 ASSERT((index >= 0) && (index < this->length()));
1963 uint8_t* ptr = external_pointer();
1964 return ptr[index];
1965}
1966
1967
1968void PixelArray::set(int index, uint8_t value) {
1969 ASSERT((index >= 0) && (index < this->length()));
1970 uint8_t* ptr = external_pointer();
1971 ptr[index] = value;
1972}
1973
1974
ager@chromium.org3811b432009-10-28 14:53:37 +00001975void* ExternalArray::external_pointer() {
1976 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1977 return reinterpret_cast<void*>(ptr);
1978}
1979
1980
1981void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1982 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1983 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1984}
1985
1986
1987int8_t ExternalByteArray::get(int index) {
1988 ASSERT((index >= 0) && (index < this->length()));
1989 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1990 return ptr[index];
1991}
1992
1993
1994void ExternalByteArray::set(int index, int8_t value) {
1995 ASSERT((index >= 0) && (index < this->length()));
1996 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1997 ptr[index] = value;
1998}
1999
2000
2001uint8_t ExternalUnsignedByteArray::get(int index) {
2002 ASSERT((index >= 0) && (index < this->length()));
2003 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2004 return ptr[index];
2005}
2006
2007
2008void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2009 ASSERT((index >= 0) && (index < this->length()));
2010 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2011 ptr[index] = value;
2012}
2013
2014
2015int16_t ExternalShortArray::get(int index) {
2016 ASSERT((index >= 0) && (index < this->length()));
2017 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2018 return ptr[index];
2019}
2020
2021
2022void ExternalShortArray::set(int index, int16_t value) {
2023 ASSERT((index >= 0) && (index < this->length()));
2024 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2025 ptr[index] = value;
2026}
2027
2028
2029uint16_t ExternalUnsignedShortArray::get(int index) {
2030 ASSERT((index >= 0) && (index < this->length()));
2031 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2032 return ptr[index];
2033}
2034
2035
2036void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2037 ASSERT((index >= 0) && (index < this->length()));
2038 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2039 ptr[index] = value;
2040}
2041
2042
2043int32_t ExternalIntArray::get(int index) {
2044 ASSERT((index >= 0) && (index < this->length()));
2045 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2046 return ptr[index];
2047}
2048
2049
2050void ExternalIntArray::set(int index, int32_t value) {
2051 ASSERT((index >= 0) && (index < this->length()));
2052 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2053 ptr[index] = value;
2054}
2055
2056
2057uint32_t ExternalUnsignedIntArray::get(int index) {
2058 ASSERT((index >= 0) && (index < this->length()));
2059 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2060 return ptr[index];
2061}
2062
2063
2064void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2065 ASSERT((index >= 0) && (index < this->length()));
2066 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2067 ptr[index] = value;
2068}
2069
2070
2071float ExternalFloatArray::get(int index) {
2072 ASSERT((index >= 0) && (index < this->length()));
2073 float* ptr = static_cast<float*>(external_pointer());
2074 return ptr[index];
2075}
2076
2077
2078void ExternalFloatArray::set(int index, float value) {
2079 ASSERT((index >= 0) && (index < this->length()));
2080 float* ptr = static_cast<float*>(external_pointer());
2081 ptr[index] = value;
2082}
2083
2084
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002086 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2087}
2088
2089
2090int Map::inobject_properties() {
2091 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002092}
2093
2094
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002095int Map::pre_allocated_property_fields() {
2096 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2097}
2098
2099
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100int HeapObject::SizeFromMap(Map* map) {
2101 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002102 // Only inline the most frequent cases.
2103 if (instance_type == JS_OBJECT_TYPE ||
2104 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2105 (kStringTag | kConsStringTag) ||
2106 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 if (instance_type == FIXED_ARRAY_TYPE) {
2108 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2109 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002110 if (instance_type == BYTE_ARRAY_TYPE) {
2111 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2112 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002113 // Otherwise do the general size computation.
2114 return SlowSizeFromMap(map);
2115}
2116
2117
2118void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002119 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002120 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121 ASSERT(0 <= value && value < 256);
2122 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2123}
2124
2125
ager@chromium.org7c537e22008-10-16 08:43:32 +00002126void Map::set_inobject_properties(int value) {
2127 ASSERT(0 <= value && value < 256);
2128 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2129}
2130
2131
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002132void Map::set_pre_allocated_property_fields(int value) {
2133 ASSERT(0 <= value && value < 256);
2134 WRITE_BYTE_FIELD(this,
2135 kPreAllocatedPropertyFieldsOffset,
2136 static_cast<byte>(value));
2137}
2138
2139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140InstanceType Map::instance_type() {
2141 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2142}
2143
2144
2145void Map::set_instance_type(InstanceType value) {
2146 ASSERT(0 <= value && value < 256);
2147 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2148}
2149
2150
2151int Map::unused_property_fields() {
2152 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2153}
2154
2155
2156void Map::set_unused_property_fields(int value) {
2157 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2158}
2159
2160
2161byte Map::bit_field() {
2162 return READ_BYTE_FIELD(this, kBitFieldOffset);
2163}
2164
2165
2166void Map::set_bit_field(byte value) {
2167 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2168}
2169
2170
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002171byte Map::bit_field2() {
2172 return READ_BYTE_FIELD(this, kBitField2Offset);
2173}
2174
2175
2176void Map::set_bit_field2(byte value) {
2177 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2178}
2179
2180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002181void Map::set_non_instance_prototype(bool value) {
2182 if (value) {
2183 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2184 } else {
2185 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2186 }
2187}
2188
2189
2190bool Map::has_non_instance_prototype() {
2191 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2192}
2193
2194
ager@chromium.org870a0b62008-11-04 11:43:05 +00002195void Map::set_is_access_check_needed(bool access_check_needed) {
2196 if (access_check_needed) {
2197 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2198 } else {
2199 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2200 }
2201}
2202
2203
2204bool Map::is_access_check_needed() {
2205 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2206}
2207
2208
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209Code::Flags Code::flags() {
2210 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2211}
2212
2213
2214void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002215 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 // Make sure that all call stubs have an arguments count.
2217 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2218 ExtractArgumentsCountFromFlags(flags) >= 0);
2219 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2220}
2221
2222
2223Code::Kind Code::kind() {
2224 return ExtractKindFromFlags(flags());
2225}
2226
2227
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002228InLoopFlag Code::ic_in_loop() {
2229 return ExtractICInLoopFromFlags(flags());
2230}
2231
2232
kasper.lund7276f142008-07-30 08:49:36 +00002233InlineCacheState Code::ic_state() {
2234 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002235 // Only allow uninitialized or debugger states for non-IC code
2236 // objects. This is used in the debugger to determine whether or not
2237 // a call to code object has been replaced with a debug break call.
2238 ASSERT(is_inline_cache_stub() ||
2239 result == UNINITIALIZED ||
2240 result == DEBUG_BREAK ||
2241 result == DEBUG_PREPARE_STEP_IN);
2242 return result;
2243}
2244
2245
2246PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002247 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248 return ExtractTypeFromFlags(flags());
2249}
2250
2251
2252int Code::arguments_count() {
2253 ASSERT(is_call_stub() || kind() == STUB);
2254 return ExtractArgumentsCountFromFlags(flags());
2255}
2256
2257
2258CodeStub::Major Code::major_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 ASSERT(kind() == STUB);
kasper.lund7276f142008-07-30 08:49:36 +00002260 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2261 kStubMajorKeyOffset));
2262}
2263
2264
2265void Code::set_major_key(CodeStub::Major major) {
2266 ASSERT(kind() == STUB);
2267 ASSERT(0 <= major && major < 256);
2268 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269}
2270
2271
2272bool Code::is_inline_cache_stub() {
2273 Kind kind = this->kind();
2274 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2275}
2276
2277
2278Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002279 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002280 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 PropertyType type,
2282 int argc) {
2283 // Compute the bit mask.
2284 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002285 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002286 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287 bits |= type << kFlagsTypeShift;
2288 bits |= argc << kFlagsArgumentsCountShift;
2289 // Cast to flags and validate result before returning it.
2290 Flags result = static_cast<Flags>(bits);
2291 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002292 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002293 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002294 ASSERT(ExtractTypeFromFlags(result) == type);
2295 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2296 return result;
2297}
2298
2299
2300Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2301 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002302 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002303 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002304 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305}
2306
2307
2308Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2309 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2310 return static_cast<Kind>(bits);
2311}
2312
2313
kasper.lund7276f142008-07-30 08:49:36 +00002314InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2315 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002316 return static_cast<InlineCacheState>(bits);
2317}
2318
2319
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002320InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2321 int bits = (flags & kFlagsICInLoopMask);
2322 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2323}
2324
2325
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2327 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2328 return static_cast<PropertyType>(bits);
2329}
2330
2331
2332int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2333 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2334}
2335
2336
2337Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2338 int bits = flags & ~kFlagsTypeMask;
2339 return static_cast<Flags>(bits);
2340}
2341
2342
ager@chromium.org8bb60582008-12-11 12:02:20 +00002343Code* Code::GetCodeFromTargetAddress(Address address) {
2344 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2345 // GetCodeFromTargetAddress might be called when marking objects during mark
2346 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2347 // Code::cast. Code::cast does not work when the object's map is
2348 // marked.
2349 Code* result = reinterpret_cast<Code*>(code);
2350 return result;
2351}
2352
2353
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354Object* Map::prototype() {
2355 return READ_FIELD(this, kPrototypeOffset);
2356}
2357
2358
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002359void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360 ASSERT(value->IsNull() || value->IsJSObject());
2361 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002362 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363}
2364
2365
2366ACCESSORS(Map, instance_descriptors, DescriptorArray,
2367 kInstanceDescriptorsOffset)
2368ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
2369ACCESSORS(Map, constructor, Object, kConstructorOffset)
2370
2371ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2372ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2373
2374ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2375ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002376ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002377
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002378ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002379
2380ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2381ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2382ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2383ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2384ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002385ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002386
2387ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2388ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2389ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2390
2391ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2392ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2393ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2394ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2395ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2396ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2397
2398ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2399ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2400
2401ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2402ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2403
2404ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2405ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002406ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2407 kPropertyAccessorsOffset)
2408ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2409 kPrototypeTemplateOffset)
2410ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2411ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2412 kNamedPropertyHandlerOffset)
2413ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2414 kIndexedPropertyHandlerOffset)
2415ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2416 kInstanceTemplateOffset)
2417ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2418ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002419ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2420 kInstanceCallHandlerOffset)
2421ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2422 kAccessCheckInfoOffset)
2423ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2424
2425ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002426ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2427 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428
2429ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2430ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2431
2432ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2433
2434ACCESSORS(Script, source, Object, kSourceOffset)
2435ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002436ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2438ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002439ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002440ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2442ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002443ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002444ACCESSORS(Script, line_ends_fixed_array, Object, kLineEndsFixedArrayOffset)
2445ACCESSORS(Script, line_ends_js_array, Object, kLineEndsJSArrayOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002446ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
2447ACCESSORS(Script, eval_from_instructions_offset, Smi,
2448 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002449
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002450#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002451ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2452ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2453ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2454ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2455
2456ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2457ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2458ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2459ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002460#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002462ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2464ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2465 kInstanceClassNameOffset)
2466ACCESSORS(SharedFunctionInfo, function_data, Object,
2467 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2469ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002470ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002471ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2472 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002473
2474BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2475 kHiddenPrototypeBit)
2476BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2477BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2478 kNeedsAccessCheckBit)
2479BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2480 kIsExpressionBit)
2481BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2482 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002483BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002484 has_only_simple_this_property_assignments,
2485 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002486BOOL_ACCESSORS(SharedFunctionInfo,
2487 compiler_hints,
2488 try_fast_codegen,
2489 kTryFastCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002490
2491INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2492INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2493 kFormalParameterCountOffset)
2494INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2495 kExpectedNofPropertiesOffset)
2496INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2497 kStartPositionAndTypeOffset)
2498INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2499INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2500 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002501INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2502 kCompilerHintsOffset)
2503INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2504 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002505
2506
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002507bool Script::HasValidSource() {
2508 Object* src = this->source();
2509 if (!src->IsString()) return true;
2510 String* src_str = String::cast(src);
2511 if (!StringShape(src_str).IsExternal()) return true;
2512 if (src_str->IsAsciiRepresentation()) {
2513 return ExternalAsciiString::cast(src)->resource() != NULL;
2514 } else if (src_str->IsTwoByteRepresentation()) {
2515 return ExternalTwoByteString::cast(src)->resource() != NULL;
2516 }
2517 return true;
2518}
2519
2520
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002521void SharedFunctionInfo::DontAdaptArguments() {
2522 ASSERT(code()->kind() == Code::BUILTIN);
2523 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2524}
2525
2526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527int SharedFunctionInfo::start_position() {
2528 return start_position_and_type() >> kStartPositionShift;
2529}
2530
2531
2532void SharedFunctionInfo::set_start_position(int start_position) {
2533 set_start_position_and_type((start_position << kStartPositionShift)
2534 | (start_position_and_type() & ~kStartPositionMask));
2535}
2536
2537
2538Code* SharedFunctionInfo::code() {
2539 return Code::cast(READ_FIELD(this, kCodeOffset));
2540}
2541
2542
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002543void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002544 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002545 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546}
2547
2548
2549bool SharedFunctionInfo::is_compiled() {
2550 // TODO(1242782): Create a code kind for uncompiled code.
2551 return code()->kind() != Code::STUB;
2552}
2553
2554
2555bool JSFunction::IsBoilerplate() {
2556 return map() == Heap::boilerplate_function_map();
2557}
2558
2559
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002560bool JSFunction::IsBuiltin() {
2561 return context()->global()->IsJSBuiltinsObject();
2562}
2563
2564
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002565bool JSObject::IsLoaded() {
2566 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567}
2568
2569
2570Code* JSFunction::code() {
2571 return shared()->code();
2572}
2573
2574
2575void JSFunction::set_code(Code* value) {
2576 shared()->set_code(value);
2577}
2578
2579
2580Context* JSFunction::context() {
2581 return Context::cast(READ_FIELD(this, kContextOffset));
2582}
2583
2584
2585Object* JSFunction::unchecked_context() {
2586 return READ_FIELD(this, kContextOffset);
2587}
2588
2589
2590void JSFunction::set_context(Object* value) {
2591 ASSERT(value == Heap::undefined_value() || value->IsContext());
2592 WRITE_FIELD(this, kContextOffset, value);
2593 WRITE_BARRIER(this, kContextOffset);
2594}
2595
2596ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2597 kPrototypeOrInitialMapOffset)
2598
2599
2600Map* JSFunction::initial_map() {
2601 return Map::cast(prototype_or_initial_map());
2602}
2603
2604
2605void JSFunction::set_initial_map(Map* value) {
2606 set_prototype_or_initial_map(value);
2607}
2608
2609
2610bool JSFunction::has_initial_map() {
2611 return prototype_or_initial_map()->IsMap();
2612}
2613
2614
2615bool JSFunction::has_instance_prototype() {
2616 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2617}
2618
2619
2620bool JSFunction::has_prototype() {
2621 return map()->has_non_instance_prototype() || has_instance_prototype();
2622}
2623
2624
2625Object* JSFunction::instance_prototype() {
2626 ASSERT(has_instance_prototype());
2627 if (has_initial_map()) return initial_map()->prototype();
2628 // When there is no initial map and the prototype is a JSObject, the
2629 // initial map field is used for the prototype field.
2630 return prototype_or_initial_map();
2631}
2632
2633
2634Object* JSFunction::prototype() {
2635 ASSERT(has_prototype());
2636 // If the function's prototype property has been set to a non-JSObject
2637 // value, that value is stored in the constructor field of the map.
2638 if (map()->has_non_instance_prototype()) return map()->constructor();
2639 return instance_prototype();
2640}
2641
2642
2643bool JSFunction::is_compiled() {
2644 return shared()->is_compiled();
2645}
2646
2647
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002648int JSFunction::NumberOfLiterals() {
2649 return literals()->length();
2650}
2651
2652
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2654 ASSERT(0 <= id && id < kJSBuiltinsCount);
2655 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2656}
2657
2658
2659void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2660 Object* value) {
2661 ASSERT(0 <= id && id < kJSBuiltinsCount);
2662 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2663 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2664}
2665
2666
2667Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002668 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002669}
2670
2671
2672void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002673 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002674}
2675
2676
2677void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2678 visitor->VisitExternalReference(
2679 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2680}
2681
2682
2683ACCESSORS(JSValue, value, Object, kValueOffset)
2684
2685
2686JSValue* JSValue::cast(Object* obj) {
2687 ASSERT(obj->IsJSValue());
2688 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2689 return reinterpret_cast<JSValue*>(obj);
2690}
2691
2692
2693INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2694INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2695INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2696
2697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002698byte* Code::instruction_start() {
2699 return FIELD_ADDR(this, kHeaderSize);
2700}
2701
2702
2703int Code::body_size() {
2704 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2705}
2706
2707
2708byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002709 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002710}
2711
2712
2713byte* Code::entry() {
2714 return instruction_start();
2715}
2716
2717
2718bool Code::contains(byte* pc) {
2719 return (instruction_start() <= pc) &&
2720 (pc < instruction_start() + instruction_size());
2721}
2722
2723
2724byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002725 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726}
2727
2728
2729ACCESSORS(JSArray, length, Object, kLengthOffset)
2730
2731
ager@chromium.org236ad962008-09-25 09:45:57 +00002732ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002733
2734
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002735JSRegExp::Type JSRegExp::TypeTag() {
2736 Object* data = this->data();
2737 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2738 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2739 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002740}
2741
2742
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002743int JSRegExp::CaptureCount() {
2744 switch (TypeTag()) {
2745 case ATOM:
2746 return 0;
2747 case IRREGEXP:
2748 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2749 default:
2750 UNREACHABLE();
2751 return -1;
2752 }
2753}
2754
2755
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002756JSRegExp::Flags JSRegExp::GetFlags() {
2757 ASSERT(this->data()->IsFixedArray());
2758 Object* data = this->data();
2759 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2760 return Flags(smi->value());
2761}
2762
2763
2764String* JSRegExp::Pattern() {
2765 ASSERT(this->data()->IsFixedArray());
2766 Object* data = this->data();
2767 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2768 return pattern;
2769}
2770
2771
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002772Object* JSRegExp::DataAt(int index) {
2773 ASSERT(TypeTag() != NOT_COMPILED);
2774 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002775}
2776
2777
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002778void JSRegExp::SetDataAt(int index, Object* value) {
2779 ASSERT(TypeTag() != NOT_COMPILED);
2780 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2781 FixedArray::cast(data())->set(index, value);
2782}
2783
2784
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002785JSObject::ElementsKind JSObject::GetElementsKind() {
2786 Array* array = elements();
2787 if (array->IsFixedArray()) {
2788 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2789 if (array->map() == Heap::fixed_array_map()) {
2790 return FAST_ELEMENTS;
2791 }
2792 ASSERT(array->IsDictionary());
2793 return DICTIONARY_ELEMENTS;
2794 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002795 if (array->IsExternalArray()) {
2796 switch (array->map()->instance_type()) {
2797 case EXTERNAL_BYTE_ARRAY_TYPE:
2798 return EXTERNAL_BYTE_ELEMENTS;
2799 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2800 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2801 case EXTERNAL_SHORT_ARRAY_TYPE:
2802 return EXTERNAL_SHORT_ELEMENTS;
2803 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2804 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2805 case EXTERNAL_INT_ARRAY_TYPE:
2806 return EXTERNAL_INT_ELEMENTS;
2807 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2808 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2809 default:
2810 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2811 return EXTERNAL_FLOAT_ELEMENTS;
2812 }
2813 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002814 ASSERT(array->IsPixelArray());
2815 return PIXEL_ELEMENTS;
2816}
2817
2818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002819bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002820 return GetElementsKind() == FAST_ELEMENTS;
2821}
2822
2823
2824bool JSObject::HasDictionaryElements() {
2825 return GetElementsKind() == DICTIONARY_ELEMENTS;
2826}
2827
2828
2829bool JSObject::HasPixelElements() {
2830 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831}
2832
2833
ager@chromium.org3811b432009-10-28 14:53:37 +00002834bool JSObject::HasExternalArrayElements() {
2835 return (HasExternalByteElements() ||
2836 HasExternalUnsignedByteElements() ||
2837 HasExternalShortElements() ||
2838 HasExternalUnsignedShortElements() ||
2839 HasExternalIntElements() ||
2840 HasExternalUnsignedIntElements() ||
2841 HasExternalFloatElements());
2842}
2843
2844
2845bool JSObject::HasExternalByteElements() {
2846 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2847}
2848
2849
2850bool JSObject::HasExternalUnsignedByteElements() {
2851 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2852}
2853
2854
2855bool JSObject::HasExternalShortElements() {
2856 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2857}
2858
2859
2860bool JSObject::HasExternalUnsignedShortElements() {
2861 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2862}
2863
2864
2865bool JSObject::HasExternalIntElements() {
2866 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2867}
2868
2869
2870bool JSObject::HasExternalUnsignedIntElements() {
2871 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2872}
2873
2874
2875bool JSObject::HasExternalFloatElements() {
2876 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2877}
2878
2879
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002880bool JSObject::HasNamedInterceptor() {
2881 return map()->has_named_interceptor();
2882}
2883
2884
2885bool JSObject::HasIndexedInterceptor() {
2886 return map()->has_indexed_interceptor();
2887}
2888
2889
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002890StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002891 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002892 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893}
2894
2895
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002896NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002897 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002898 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002899}
2900
2901
2902bool String::HasHashCode() {
2903 return (length_field() & kHashComputedMask) != 0;
2904}
2905
2906
2907uint32_t String::Hash() {
2908 // Fast case: has hash code already been computed?
ager@chromium.org7c537e22008-10-16 08:43:32 +00002909 uint32_t field = length_field();
2910 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002911 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912 return ComputeAndSetHash();
2913}
2914
2915
ager@chromium.org7c537e22008-10-16 08:43:32 +00002916StringHasher::StringHasher(int length)
2917 : length_(length),
2918 raw_running_hash_(0),
2919 array_index_(0),
2920 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2921 is_first_char_(true),
2922 is_valid_(true) { }
2923
2924
2925bool StringHasher::has_trivial_hash() {
ager@chromium.org3811b432009-10-28 14:53:37 +00002926 return length_ > String::kMaxMediumSize;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002927}
2928
2929
2930void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002931 // Use the Jenkins one-at-a-time hash function to update the hash
2932 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002933 raw_running_hash_ += c;
2934 raw_running_hash_ += (raw_running_hash_ << 10);
2935 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002936 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002937 if (is_array_index_) {
2938 if (c < '0' || c > '9') {
2939 is_array_index_ = false;
2940 } else {
2941 int d = c - '0';
2942 if (is_first_char_) {
2943 is_first_char_ = false;
2944 if (c == '0' && length_ > 1) {
2945 is_array_index_ = false;
2946 return;
2947 }
2948 }
2949 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2950 is_array_index_ = false;
2951 } else {
2952 array_index_ = array_index_ * 10 + d;
2953 }
2954 }
2955 }
2956}
2957
2958
2959void StringHasher::AddCharacterNoIndex(uc32 c) {
2960 ASSERT(!is_array_index());
2961 raw_running_hash_ += c;
2962 raw_running_hash_ += (raw_running_hash_ << 10);
2963 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2964}
2965
2966
2967uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002968 // Get the calculated raw hash value and do some more bit ops to distribute
2969 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002970 uint32_t result = raw_running_hash_;
2971 result += (result << 3);
2972 result ^= (result >> 11);
2973 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002974 if (result == 0) {
2975 result = 27;
2976 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002977 return result;
2978}
2979
2980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002981bool String::AsArrayIndex(uint32_t* index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002982 uint32_t field = length_field();
2983 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984 return SlowAsArrayIndex(index);
2985}
2986
2987
2988Object* JSObject::GetPrototype() {
2989 return JSObject::cast(this)->map()->prototype();
2990}
2991
2992
2993PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2994 return GetPropertyAttributeWithReceiver(this, key);
2995}
2996
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002997// TODO(504): this may be useful in other places too where JSGlobalProxy
2998// is used.
2999Object* JSObject::BypassGlobalProxy() {
3000 if (IsJSGlobalProxy()) {
3001 Object* proto = GetPrototype();
3002 if (proto->IsNull()) return Heap::undefined_value();
3003 ASSERT(proto->IsJSGlobalObject());
3004 return proto;
3005 }
3006 return this;
3007}
3008
3009
3010bool JSObject::HasHiddenPropertiesObject() {
3011 ASSERT(!IsJSGlobalProxy());
3012 return GetPropertyAttributePostInterceptor(this,
3013 Heap::hidden_symbol(),
3014 false) != ABSENT;
3015}
3016
3017
3018Object* JSObject::GetHiddenPropertiesObject() {
3019 ASSERT(!IsJSGlobalProxy());
3020 PropertyAttributes attributes;
3021 return GetLocalPropertyPostInterceptor(this,
3022 Heap::hidden_symbol(),
3023 &attributes);
3024}
3025
3026
3027Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
3028 ASSERT(!IsJSGlobalProxy());
3029 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3030 hidden_obj,
3031 DONT_ENUM);
3032}
3033
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034
3035bool JSObject::HasElement(uint32_t index) {
3036 return HasElementWithReceiver(this, index);
3037}
3038
3039
3040bool AccessorInfo::all_can_read() {
3041 return BooleanBit::get(flag(), kAllCanReadBit);
3042}
3043
3044
3045void AccessorInfo::set_all_can_read(bool value) {
3046 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3047}
3048
3049
3050bool AccessorInfo::all_can_write() {
3051 return BooleanBit::get(flag(), kAllCanWriteBit);
3052}
3053
3054
3055void AccessorInfo::set_all_can_write(bool value) {
3056 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3057}
3058
3059
ager@chromium.org870a0b62008-11-04 11:43:05 +00003060bool AccessorInfo::prohibits_overwriting() {
3061 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3062}
3063
3064
3065void AccessorInfo::set_prohibits_overwriting(bool value) {
3066 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3067}
3068
3069
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070PropertyAttributes AccessorInfo::property_attributes() {
3071 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3072}
3073
3074
3075void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3076 ASSERT(AttributesField::is_valid(attributes));
3077 int rest_value = flag()->value() & ~AttributesField::mask();
3078 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3079}
3080
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003081template<typename Shape, typename Key>
3082void Dictionary<Shape, Key>::SetEntry(int entry,
3083 Object* key,
3084 Object* value,
3085 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003086 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003087 int index = HashTable<Shape, Key>::EntryToIndex(entry);
3088 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode();
3089 FixedArray::set(index, key, mode);
3090 FixedArray::set(index+1, value, mode);
3091 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003092}
3093
3094
3095void Map::ClearCodeCache() {
3096 // No write barrier is needed since empty_fixed_array is not in new space.
3097 // Please note this function is used during marking:
3098 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003099 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3100 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003101}
3102
3103
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003104void JSArray::EnsureSize(int required_size) {
3105 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003106 Array* elts = elements();
3107 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3108 if (elts->length() < required_size) {
3109 // Doubling in size would be overkill, but leave some slack to avoid
3110 // constantly growing.
3111 Expand(required_size + (required_size >> 3));
3112 // It's a performance benefit to keep a frequently used array in new-space.
3113 } else if (!Heap::new_space()->Contains(elts) &&
3114 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3115 // Expand will allocate a new backing store in new space even if the size
3116 // we asked for isn't larger than what we had before.
3117 Expand(required_size);
3118 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003119}
3120
3121
ager@chromium.org7c537e22008-10-16 08:43:32 +00003122void JSArray::SetContent(FixedArray* storage) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003123 set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
ager@chromium.org7c537e22008-10-16 08:43:32 +00003124 set_elements(storage);
3125}
3126
3127
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003128Object* FixedArray::Copy() {
3129 if (length() == 0) return this;
3130 return Heap::CopyFixedArray(this);
3131}
3132
3133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134#undef CAST_ACCESSOR
3135#undef INT_ACCESSORS
3136#undef SMI_ACCESSORS
3137#undef ACCESSORS
3138#undef FIELD_ADDR
3139#undef READ_FIELD
3140#undef WRITE_FIELD
3141#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003142#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143#undef READ_MEMADDR_FIELD
3144#undef WRITE_MEMADDR_FIELD
3145#undef READ_DOUBLE_FIELD
3146#undef WRITE_DOUBLE_FIELD
3147#undef READ_INT_FIELD
3148#undef WRITE_INT_FIELD
3149#undef READ_SHORT_FIELD
3150#undef WRITE_SHORT_FIELD
3151#undef READ_BYTE_FIELD
3152#undef WRITE_BYTE_FIELD
3153
3154
3155} } // namespace v8::internal
3156
3157#endif // V8_OBJECTS_INL_H_