blob: 1852b549bf1802c351297f3363ddac401386e66c [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
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
42#include "memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
49PropertyDetails::PropertyDetails(Smi* smi) {
50 value_ = smi->value();
51}
52
53
54Smi* PropertyDetails::AsSmi() {
55 return Smi::FromInt(value_);
56}
57
58
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000059PropertyDetails PropertyDetails::AsDeleted() {
60 PropertyDetails d(DONT_ENUM, NORMAL);
61 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
62 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000082 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083 }
84
85
86#define SMI_ACCESSORS(holder, name, offset) \
87 int holder::name() { \
88 Object* value = READ_FIELD(this, offset); \
89 return Smi::cast(value)->value(); \
90 } \
91 void holder::set_##name(int value) { \
92 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
93 }
94
95
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000096#define BOOL_GETTER(holder, field, name, offset) \
97 bool holder::name() { \
98 return BooleanBit::get(field(), offset); \
99 } \
100
101
102#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000103 bool holder::name() { \
104 return BooleanBit::get(field(), offset); \
105 } \
106 void holder::set_##name(bool value) { \
107 set_##field(BooleanBit::set(field(), offset, value)); \
108 }
109
110
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000111bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
112 // There is a constraint on the object; check.
113 if (!this->IsJSObject()) return false;
114 // Fetch the constructor function of the object.
115 Object* cons_obj = JSObject::cast(this)->map()->constructor();
116 if (!cons_obj->IsJSFunction()) return false;
117 JSFunction* fun = JSFunction::cast(cons_obj);
118 // Iterate through the chain of inheriting function templates to
119 // see if the required one occurs.
120 for (Object* type = fun->shared()->function_data();
121 type->IsFunctionTemplateInfo();
122 type = FunctionTemplateInfo::cast(type)->parent_template()) {
123 if (type == expected) return true;
124 }
125 // Didn't find the required type in the inheritance chain.
126 return false;
127}
128
129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130bool Object::IsSmi() {
131 return HAS_SMI_TAG(this);
132}
133
134
135bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000136 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000137}
138
139
140bool Object::IsHeapNumber() {
141 return Object::IsHeapObject()
142 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
143}
144
145
146bool Object::IsString() {
147 return Object::IsHeapObject()
148 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
149}
150
151
ager@chromium.org870a0b62008-11-04 11:43:05 +0000152bool Object::IsSymbol() {
153 if (!this->IsHeapObject()) return false;
154 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000155 // Because the symbol tag is non-zero and no non-string types have the
156 // symbol bit set we can test for symbols with a very simple test
157 // operation.
158 ASSERT(kSymbolTag != 0);
159 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
160 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161}
162
163
164bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000165 if (!this->IsHeapObject()) return false;
166 uint32_t type = HeapObject::cast(this)->map()->instance_type();
167 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
168 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169}
170
171
ager@chromium.org870a0b62008-11-04 11:43:05 +0000172bool Object::IsSeqString() {
173 if (!IsString()) return false;
174 return StringShape(String::cast(this)).IsSequential();
175}
176
177
178bool Object::IsSeqAsciiString() {
179 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000180 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000181 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000182}
183
184
185bool Object::IsSeqTwoByteString() {
186 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000187 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000188 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189}
190
191
192bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000193 if (!IsString()) return false;
194 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000195}
196
197
198bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000199 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000200 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000201 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202}
203
204
205bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000206 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000207 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000208 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209}
210
211
ager@chromium.org870a0b62008-11-04 11:43:05 +0000212StringShape::StringShape(String* str)
213 : type_(str->map()->instance_type()) {
214 set_valid();
215 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216}
217
218
ager@chromium.org870a0b62008-11-04 11:43:05 +0000219StringShape::StringShape(Map* map)
220 : type_(map->instance_type()) {
221 set_valid();
222 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223}
224
225
ager@chromium.org870a0b62008-11-04 11:43:05 +0000226StringShape::StringShape(InstanceType t)
227 : type_(static_cast<uint32_t>(t)) {
228 set_valid();
229 ASSERT((type_ & kIsNotStringMask) == kStringTag);
230}
231
232
233bool StringShape::IsSymbol() {
234 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000235 ASSERT(kSymbolTag != 0);
236 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000237}
238
239
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240bool String::IsAsciiRepresentation() {
241 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000242 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000243}
244
245
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246bool String::IsTwoByteRepresentation() {
247 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000249}
250
251
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000252bool String::HasOnlyAsciiChars() {
253 uint32_t type = map()->instance_type();
254 return (type & kStringEncodingMask) == kAsciiStringTag ||
255 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000256}
257
258
ager@chromium.org870a0b62008-11-04 11:43:05 +0000259bool StringShape::IsCons() {
260 return (type_ & kStringRepresentationMask) == kConsStringTag;
261}
262
263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264bool StringShape::IsExternal() {
265 return (type_ & kStringRepresentationMask) == kExternalStringTag;
266}
267
268
269bool StringShape::IsSequential() {
270 return (type_ & kStringRepresentationMask) == kSeqStringTag;
271}
272
273
274StringRepresentationTag StringShape::representation_tag() {
275 uint32_t tag = (type_ & kStringRepresentationMask);
276 return static_cast<StringRepresentationTag>(tag);
277}
278
279
280uint32_t StringShape::full_representation_tag() {
281 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
282}
283
284
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000285STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
286 Internals::kFullStringRepresentationMask);
287
288
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289bool StringShape::IsSequentialAscii() {
290 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
291}
292
293
294bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000295 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000296}
297
298
299bool StringShape::IsExternalAscii() {
300 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
301}
302
303
304bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000305 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306}
307
308
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000309STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
310 Internals::kExternalTwoByteRepresentationTag);
311
312
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000313uc32 FlatStringReader::Get(int index) {
314 ASSERT(0 <= index && index <= length_);
315 if (is_ascii_) {
316 return static_cast<const byte*>(start_)[index];
317 } else {
318 return static_cast<const uc16*>(start_)[index];
319 }
320}
321
322
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000323bool Object::IsNumber() {
324 return IsSmi() || IsHeapNumber();
325}
326
327
328bool Object::IsByteArray() {
329 return Object::IsHeapObject()
330 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
331}
332
333
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000334bool Object::IsPixelArray() {
335 return Object::IsHeapObject() &&
336 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
337}
338
339
ager@chromium.org3811b432009-10-28 14:53:37 +0000340bool Object::IsExternalArray() {
341 if (!Object::IsHeapObject())
342 return false;
343 InstanceType instance_type =
344 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000345 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
346 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000347}
348
349
350bool Object::IsExternalByteArray() {
351 return Object::IsHeapObject() &&
352 HeapObject::cast(this)->map()->instance_type() ==
353 EXTERNAL_BYTE_ARRAY_TYPE;
354}
355
356
357bool Object::IsExternalUnsignedByteArray() {
358 return Object::IsHeapObject() &&
359 HeapObject::cast(this)->map()->instance_type() ==
360 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
361}
362
363
364bool Object::IsExternalShortArray() {
365 return Object::IsHeapObject() &&
366 HeapObject::cast(this)->map()->instance_type() ==
367 EXTERNAL_SHORT_ARRAY_TYPE;
368}
369
370
371bool Object::IsExternalUnsignedShortArray() {
372 return Object::IsHeapObject() &&
373 HeapObject::cast(this)->map()->instance_type() ==
374 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
375}
376
377
378bool Object::IsExternalIntArray() {
379 return Object::IsHeapObject() &&
380 HeapObject::cast(this)->map()->instance_type() ==
381 EXTERNAL_INT_ARRAY_TYPE;
382}
383
384
385bool Object::IsExternalUnsignedIntArray() {
386 return Object::IsHeapObject() &&
387 HeapObject::cast(this)->map()->instance_type() ==
388 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
389}
390
391
392bool Object::IsExternalFloatArray() {
393 return Object::IsHeapObject() &&
394 HeapObject::cast(this)->map()->instance_type() ==
395 EXTERNAL_FLOAT_ARRAY_TYPE;
396}
397
398
lrn@chromium.org303ada72010-10-27 09:33:13 +0000399bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400 return HAS_FAILURE_TAG(this);
401}
402
403
lrn@chromium.org303ada72010-10-27 09:33:13 +0000404bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405 return HAS_FAILURE_TAG(this)
406 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
407}
408
409
lrn@chromium.org303ada72010-10-27 09:33:13 +0000410bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000411 return HAS_FAILURE_TAG(this)
412 && Failure::cast(this)->IsOutOfMemoryException();
413}
414
415
lrn@chromium.org303ada72010-10-27 09:33:13 +0000416bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417 return this == Failure::Exception();
418}
419
420
lrn@chromium.org303ada72010-10-27 09:33:13 +0000421bool MaybeObject::IsTheHole() {
422 return this == Heap::the_hole_value();
423}
424
425
426Failure* Failure::cast(MaybeObject* obj) {
427 ASSERT(HAS_FAILURE_TAG(obj));
428 return reinterpret_cast<Failure*>(obj);
429}
430
431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000432bool Object::IsJSObject() {
433 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000434 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000435}
436
437
ager@chromium.org32912102009-01-16 10:38:43 +0000438bool Object::IsJSContextExtensionObject() {
439 return IsHeapObject()
440 && (HeapObject::cast(this)->map()->instance_type() ==
441 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
442}
443
444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445bool Object::IsMap() {
446 return Object::IsHeapObject()
447 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
448}
449
450
451bool Object::IsFixedArray() {
452 return Object::IsHeapObject()
453 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
454}
455
456
457bool Object::IsDescriptorArray() {
458 return IsFixedArray();
459}
460
461
462bool Object::IsContext() {
463 return Object::IsHeapObject()
464 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000465 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000466 HeapObject::cast(this)->map() == Heap::global_context_map());
467}
468
469
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000470bool Object::IsCatchContext() {
471 return Object::IsHeapObject()
472 && HeapObject::cast(this)->map() == Heap::catch_context_map();
473}
474
475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476bool Object::IsGlobalContext() {
477 return Object::IsHeapObject()
478 && HeapObject::cast(this)->map() == Heap::global_context_map();
479}
480
481
482bool Object::IsJSFunction() {
483 return Object::IsHeapObject()
484 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
485}
486
487
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000488template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489 return obj->IsJSFunction();
490}
491
492
493bool Object::IsCode() {
494 return Object::IsHeapObject()
495 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
496}
497
498
499bool Object::IsOddball() {
500 return Object::IsHeapObject()
501 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
502}
503
504
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000505bool Object::IsJSGlobalPropertyCell() {
506 return Object::IsHeapObject()
507 && HeapObject::cast(this)->map()->instance_type()
508 == JS_GLOBAL_PROPERTY_CELL_TYPE;
509}
510
511
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000512bool Object::IsSharedFunctionInfo() {
513 return Object::IsHeapObject() &&
514 (HeapObject::cast(this)->map()->instance_type() ==
515 SHARED_FUNCTION_INFO_TYPE);
516}
517
518
519bool Object::IsJSValue() {
520 return Object::IsHeapObject()
521 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
522}
523
524
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000525bool Object::IsStringWrapper() {
526 return IsJSValue() && JSValue::cast(this)->value()->IsString();
527}
528
529
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000530bool Object::IsProxy() {
531 return Object::IsHeapObject()
532 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
533}
534
535
536bool Object::IsBoolean() {
537 return IsTrue() || IsFalse();
538}
539
540
541bool Object::IsJSArray() {
542 return Object::IsHeapObject()
543 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
544}
545
546
ager@chromium.org236ad962008-09-25 09:45:57 +0000547bool Object::IsJSRegExp() {
548 return Object::IsHeapObject()
549 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
550}
551
552
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000553template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000554 return obj->IsJSArray();
555}
556
557
558bool Object::IsHashTable() {
559 return Object::IsHeapObject()
560 && HeapObject::cast(this)->map() == Heap::hash_table_map();
561}
562
563
564bool Object::IsDictionary() {
565 return IsHashTable() && this != Heap::symbol_table();
566}
567
568
569bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000570 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571}
572
573
ager@chromium.orgac091b72010-05-05 07:34:42 +0000574bool Object::IsJSFunctionResultCache() {
575 if (!IsFixedArray()) return false;
576 FixedArray* self = FixedArray::cast(this);
577 int length = self->length();
578 if (length < JSFunctionResultCache::kEntriesIndex) return false;
579 if ((length - JSFunctionResultCache::kEntriesIndex)
580 % JSFunctionResultCache::kEntrySize != 0) {
581 return false;
582 }
583#ifdef DEBUG
584 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
585#endif
586 return true;
587}
588
589
ricow@chromium.org65fae842010-08-25 15:26:24 +0000590bool Object::IsNormalizedMapCache() {
591 if (!IsFixedArray()) return false;
592 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
593 return false;
594 }
595#ifdef DEBUG
596 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
597#endif
598 return true;
599}
600
601
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000602bool Object::IsCompilationCacheTable() {
603 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000604}
605
606
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000607bool Object::IsCodeCacheHashTable() {
608 return IsHashTable();
609}
610
611
ager@chromium.org236ad962008-09-25 09:45:57 +0000612bool Object::IsMapCache() {
613 return IsHashTable();
614}
615
616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617bool Object::IsPrimitive() {
618 return IsOddball() || IsNumber() || IsString();
619}
620
621
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000622bool Object::IsJSGlobalProxy() {
623 bool result = IsHeapObject() &&
624 (HeapObject::cast(this)->map()->instance_type() ==
625 JS_GLOBAL_PROXY_TYPE);
626 ASSERT(!result || IsAccessCheckNeeded());
627 return result;
628}
629
630
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000632 if (!IsHeapObject()) return false;
633
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000634 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000635 return type == JS_GLOBAL_OBJECT_TYPE ||
636 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000637}
638
639
640bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641 return IsHeapObject() &&
642 (HeapObject::cast(this)->map()->instance_type() ==
643 JS_GLOBAL_OBJECT_TYPE);
644}
645
646
647bool Object::IsJSBuiltinsObject() {
648 return IsHeapObject() &&
649 (HeapObject::cast(this)->map()->instance_type() ==
650 JS_BUILTINS_OBJECT_TYPE);
651}
652
653
654bool Object::IsUndetectableObject() {
655 return IsHeapObject()
656 && HeapObject::cast(this)->map()->is_undetectable();
657}
658
659
660bool Object::IsAccessCheckNeeded() {
661 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000662 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
666bool Object::IsStruct() {
667 if (!IsHeapObject()) return false;
668 switch (HeapObject::cast(this)->map()->instance_type()) {
669#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
670 STRUCT_LIST(MAKE_STRUCT_CASE)
671#undef MAKE_STRUCT_CASE
672 default: return false;
673 }
674}
675
676
677#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
678 bool Object::Is##Name() { \
679 return Object::IsHeapObject() \
680 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
681 }
682 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
683#undef MAKE_STRUCT_PREDICATE
684
685
686bool Object::IsUndefined() {
687 return this == Heap::undefined_value();
688}
689
690
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000691bool Object::IsNull() {
692 return this == Heap::null_value();
693}
694
695
696bool Object::IsTrue() {
697 return this == Heap::true_value();
698}
699
700
701bool Object::IsFalse() {
702 return this == Heap::false_value();
703}
704
705
706double Object::Number() {
707 ASSERT(IsNumber());
708 return IsSmi()
709 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
710 : reinterpret_cast<HeapNumber*>(this)->value();
711}
712
713
714
lrn@chromium.org303ada72010-10-27 09:33:13 +0000715MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716 if (IsSmi()) return this;
717 if (IsHeapNumber()) {
718 double value = HeapNumber::cast(this)->value();
719 int int_value = FastD2I(value);
720 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
721 return Smi::FromInt(int_value);
722 }
723 }
724 return Failure::Exception();
725}
726
727
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728bool Object::HasSpecificClassOf(String* name) {
729 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
730}
731
732
lrn@chromium.org303ada72010-10-27 09:33:13 +0000733MaybeObject* Object::GetElement(uint32_t index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000734 return GetElementWithReceiver(this, index);
735}
736
737
lrn@chromium.org303ada72010-10-27 09:33:13 +0000738Object* Object::GetElementNoExceptionThrown(uint32_t index) {
739 MaybeObject* maybe = GetElementWithReceiver(this, index);
740 ASSERT(!maybe->IsFailure());
741 Object* result = NULL; // Initialization to please compiler.
742 maybe->ToObject(&result);
743 return result;
744}
745
746
747MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748 PropertyAttributes attributes;
749 return GetPropertyWithReceiver(this, key, &attributes);
750}
751
752
lrn@chromium.org303ada72010-10-27 09:33:13 +0000753MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754 return GetPropertyWithReceiver(this, key, attributes);
755}
756
757
758#define FIELD_ADDR(p, offset) \
759 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
760
761#define READ_FIELD(p, offset) \
762 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
763
764#define WRITE_FIELD(p, offset, value) \
765 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
766
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000767
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000768#define WRITE_BARRIER(object, offset) \
769 Heap::RecordWrite(object->address(), offset);
770
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000771// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000772// write due to the assert validating the written value.
773#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
774 if (mode == UPDATE_WRITE_BARRIER) { \
775 Heap::RecordWrite(object->address(), offset); \
776 } else { \
777 ASSERT(mode == SKIP_WRITE_BARRIER); \
778 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000779 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000780 Page::FromAddress(object->address())-> \
781 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000782 }
783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784#define READ_DOUBLE_FIELD(p, offset) \
785 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
786
787#define WRITE_DOUBLE_FIELD(p, offset, value) \
788 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
789
790#define READ_INT_FIELD(p, offset) \
791 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
792
793#define WRITE_INT_FIELD(p, offset, value) \
794 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
795
ager@chromium.org3e875802009-06-29 08:26:34 +0000796#define READ_INTPTR_FIELD(p, offset) \
797 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
798
799#define WRITE_INTPTR_FIELD(p, offset, value) \
800 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
801
ager@chromium.org7c537e22008-10-16 08:43:32 +0000802#define READ_UINT32_FIELD(p, offset) \
803 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
804
805#define WRITE_UINT32_FIELD(p, offset, value) \
806 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808#define READ_SHORT_FIELD(p, offset) \
809 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
810
811#define WRITE_SHORT_FIELD(p, offset, value) \
812 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
813
814#define READ_BYTE_FIELD(p, offset) \
815 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
816
817#define WRITE_BYTE_FIELD(p, offset, value) \
818 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
819
820
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000821Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
822 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000823}
824
825
826int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000827 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828}
829
830
831Smi* Smi::FromInt(int value) {
832 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000833 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000834 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000835 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000836 return reinterpret_cast<Smi*>(tagged_value);
837}
838
839
840Smi* Smi::FromIntptr(intptr_t value) {
841 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000842 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
843 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000844}
845
846
847Failure::Type Failure::type() const {
848 return static_cast<Type>(value() & kFailureTypeTagMask);
849}
850
851
852bool Failure::IsInternalError() const {
853 return type() == INTERNAL_ERROR;
854}
855
856
857bool Failure::IsOutOfMemoryException() const {
858 return type() == OUT_OF_MEMORY_EXCEPTION;
859}
860
861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000862AllocationSpace Failure::allocation_space() const {
863 ASSERT_EQ(RETRY_AFTER_GC, type());
864 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
865 & kSpaceTagMask);
866}
867
868
869Failure* Failure::InternalError() {
870 return Construct(INTERNAL_ERROR);
871}
872
873
874Failure* Failure::Exception() {
875 return Construct(EXCEPTION);
876}
877
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000878
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879Failure* Failure::OutOfMemoryException() {
880 return Construct(OUT_OF_MEMORY_EXCEPTION);
881}
882
883
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000884intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000885 return static_cast<intptr_t>(
886 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887}
888
889
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000890Failure* Failure::RetryAfterGC() {
891 return RetryAfterGC(NEW_SPACE);
892}
893
894
895Failure* Failure::RetryAfterGC(AllocationSpace space) {
896 ASSERT((space & ~kSpaceTagMask) == 0);
897 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000898}
899
900
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000901Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000902 uintptr_t info =
903 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000904 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000905 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906}
907
908
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000909bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910#ifdef DEBUG
911 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
912#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000913
914#ifdef V8_TARGET_ARCH_X64
915 // To be representable as a long smi, the value must be a 32-bit integer.
916 bool result = (value == static_cast<int32_t>(value));
917#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000918 // To be representable as an tagged small integer, the two
919 // most-significant bits of 'value' must be either 00 or 11 due to
920 // sign-extension. To check this we add 01 to the two
921 // most-significant bits, and check if the most-significant bit is 0
922 //
923 // CAUTION: The original code below:
924 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
925 // may lead to incorrect results according to the C language spec, and
926 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
927 // compiler may produce undefined results in case of signed integer
928 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000929 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000930#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000931 ASSERT(result == in_range);
932 return result;
933}
934
935
kasper.lund7276f142008-07-30 08:49:36 +0000936MapWord MapWord::FromMap(Map* map) {
937 return MapWord(reinterpret_cast<uintptr_t>(map));
938}
939
940
941Map* MapWord::ToMap() {
942 return reinterpret_cast<Map*>(value_);
943}
944
945
946bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000947 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000948}
949
950
951MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000952 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
953 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000954}
955
956
957HeapObject* MapWord::ToForwardingAddress() {
958 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000959 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000960}
961
962
963bool MapWord::IsMarked() {
964 return (value_ & kMarkingMask) == 0;
965}
966
967
968void MapWord::SetMark() {
969 value_ &= ~kMarkingMask;
970}
971
972
973void MapWord::ClearMark() {
974 value_ |= kMarkingMask;
975}
976
977
978bool MapWord::IsOverflowed() {
979 return (value_ & kOverflowMask) != 0;
980}
981
982
983void MapWord::SetOverflow() {
984 value_ |= kOverflowMask;
985}
986
987
988void MapWord::ClearOverflow() {
989 value_ &= ~kOverflowMask;
990}
991
992
993MapWord MapWord::EncodeAddress(Address map_address, int offset) {
994 // Offset is the distance in live bytes from the first live object in the
995 // same page. The offset between two objects in the same page should not
996 // exceed the object area size of a page.
997 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
998
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000999 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001000 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1001
1002 Page* map_page = Page::FromAddress(map_address);
1003 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1004
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001005 uintptr_t map_page_offset =
1006 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001007
1008 uintptr_t encoding =
1009 (compact_offset << kForwardingOffsetShift) |
1010 (map_page_offset << kMapPageOffsetShift) |
1011 (map_page->mc_page_index << kMapPageIndexShift);
1012 return MapWord(encoding);
1013}
1014
1015
1016Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001017 int map_page_index =
1018 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001019 ASSERT_MAP_PAGE_INDEX(map_page_index);
1020
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001021 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001022 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1023 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001024
1025 return (map_space->PageAddress(map_page_index) + map_page_offset);
1026}
1027
1028
1029int MapWord::DecodeOffset() {
1030 // The offset field is represented in the kForwardingOffsetBits
1031 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001032 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1033 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1034 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001035}
1036
1037
1038MapWord MapWord::FromEncodedAddress(Address address) {
1039 return MapWord(reinterpret_cast<uintptr_t>(address));
1040}
1041
1042
1043Address MapWord::ToEncodedAddress() {
1044 return reinterpret_cast<Address>(value_);
1045}
1046
1047
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048#ifdef DEBUG
1049void HeapObject::VerifyObjectField(int offset) {
1050 VerifyPointer(READ_FIELD(this, offset));
1051}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001052
1053void HeapObject::VerifySmiField(int offset) {
1054 ASSERT(READ_FIELD(this, offset)->IsSmi());
1055}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056#endif
1057
1058
1059Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001060 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061}
1062
1063
1064void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001065 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066}
1067
1068
kasper.lund7276f142008-07-30 08:49:36 +00001069MapWord HeapObject::map_word() {
1070 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1071}
1072
1073
1074void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001075 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001076 // here.
1077 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1078}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079
1080
1081HeapObject* HeapObject::FromAddress(Address address) {
1082 ASSERT_TAG_ALIGNED(address);
1083 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1084}
1085
1086
1087Address HeapObject::address() {
1088 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1089}
1090
1091
1092int HeapObject::Size() {
1093 return SizeFromMap(map());
1094}
1095
1096
1097void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1098 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1099 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1100}
1101
1102
1103void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1104 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1105}
1106
1107
kasper.lund7276f142008-07-30 08:49:36 +00001108bool HeapObject::IsMarked() {
1109 return map_word().IsMarked();
1110}
1111
1112
1113void HeapObject::SetMark() {
1114 ASSERT(!IsMarked());
1115 MapWord first_word = map_word();
1116 first_word.SetMark();
1117 set_map_word(first_word);
1118}
1119
1120
1121void HeapObject::ClearMark() {
1122 ASSERT(IsMarked());
1123 MapWord first_word = map_word();
1124 first_word.ClearMark();
1125 set_map_word(first_word);
1126}
1127
1128
1129bool HeapObject::IsOverflowed() {
1130 return map_word().IsOverflowed();
1131}
1132
1133
1134void HeapObject::SetOverflow() {
1135 MapWord first_word = map_word();
1136 first_word.SetOverflow();
1137 set_map_word(first_word);
1138}
1139
1140
1141void HeapObject::ClearOverflow() {
1142 ASSERT(IsOverflowed());
1143 MapWord first_word = map_word();
1144 first_word.ClearOverflow();
1145 set_map_word(first_word);
1146}
1147
1148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001149double HeapNumber::value() {
1150 return READ_DOUBLE_FIELD(this, kValueOffset);
1151}
1152
1153
1154void HeapNumber::set_value(double value) {
1155 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1156}
1157
1158
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001159int HeapNumber::get_exponent() {
1160 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1161 kExponentShift) - kExponentBias;
1162}
1163
1164
1165int HeapNumber::get_sign() {
1166 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1167}
1168
1169
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001170ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001171
1172
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001173HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001174 Object* array = READ_FIELD(this, kElementsOffset);
1175 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001176 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1177 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001178 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001179}
1180
1181
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001182void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001183 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001184 (value->map() == Heap::fixed_array_map() ||
1185 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001186 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001187 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1188 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001189 WRITE_FIELD(this, kElementsOffset, value);
1190 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1191}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192
1193
1194void JSObject::initialize_properties() {
1195 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1196 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1197}
1198
1199
1200void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001201 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1203 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1204}
1205
1206
lrn@chromium.org303ada72010-10-27 09:33:13 +00001207MaybeObject* JSObject::ResetElements() {
1208 Object* obj;
1209 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1210 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1211 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001212 set_map(Map::cast(obj));
1213 initialize_elements();
1214 return this;
1215}
1216
1217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001218ACCESSORS(Oddball, to_string, String, kToStringOffset)
1219ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1220
1221
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001222Object* JSGlobalPropertyCell::value() {
1223 return READ_FIELD(this, kValueOffset);
1224}
1225
1226
1227void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1228 // The write barrier is not used for global property cells.
1229 ASSERT(!val->IsJSGlobalPropertyCell());
1230 WRITE_FIELD(this, kValueOffset, val);
1231}
1232
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001233
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001235 InstanceType type = map()->instance_type();
1236 // Check for the most common kind of JavaScript object before
1237 // falling into the generic switch. This speeds up the internal
1238 // field operations considerably on average.
1239 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1240 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001241 case JS_GLOBAL_PROXY_TYPE:
1242 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001243 case JS_GLOBAL_OBJECT_TYPE:
1244 return JSGlobalObject::kSize;
1245 case JS_BUILTINS_OBJECT_TYPE:
1246 return JSBuiltinsObject::kSize;
1247 case JS_FUNCTION_TYPE:
1248 return JSFunction::kSize;
1249 case JS_VALUE_TYPE:
1250 return JSValue::kSize;
1251 case JS_ARRAY_TYPE:
1252 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001253 case JS_REGEXP_TYPE:
1254 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001255 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256 return JSObject::kHeaderSize;
1257 default:
1258 UNREACHABLE();
1259 return 0;
1260 }
1261}
1262
1263
1264int JSObject::GetInternalFieldCount() {
1265 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001266 // Make sure to adjust for the number of in-object properties. These
1267 // properties do contribute to the size, but are not internal fields.
1268 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1269 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001270}
1271
1272
1273Object* JSObject::GetInternalField(int index) {
1274 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001275 // Internal objects do follow immediately after the header, whereas in-object
1276 // properties are at the end of the object. Therefore there is no need
1277 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1279}
1280
1281
1282void JSObject::SetInternalField(int index, Object* value) {
1283 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001284 // Internal objects do follow immediately after the header, whereas in-object
1285 // properties are at the end of the object. Therefore there is no need
1286 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001287 int offset = GetHeaderSize() + (kPointerSize * index);
1288 WRITE_FIELD(this, offset, value);
1289 WRITE_BARRIER(this, offset);
1290}
1291
1292
ager@chromium.org7c537e22008-10-16 08:43:32 +00001293// Access fast-case object properties at index. The use of these routines
1294// is needed to correctly distinguish between properties stored in-object and
1295// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001296Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001297 // Adjust for the number of properties stored in the object.
1298 index -= map()->inobject_properties();
1299 if (index < 0) {
1300 int offset = map()->instance_size() + (index * kPointerSize);
1301 return READ_FIELD(this, offset);
1302 } else {
1303 ASSERT(index < properties()->length());
1304 return properties()->get(index);
1305 }
1306}
1307
1308
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001309Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001310 // Adjust for the number of properties stored in the object.
1311 index -= map()->inobject_properties();
1312 if (index < 0) {
1313 int offset = map()->instance_size() + (index * kPointerSize);
1314 WRITE_FIELD(this, offset, value);
1315 WRITE_BARRIER(this, offset);
1316 } else {
1317 ASSERT(index < properties()->length());
1318 properties()->set(index, value);
1319 }
1320 return value;
1321}
1322
1323
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001324Object* JSObject::InObjectPropertyAt(int index) {
1325 // Adjust for the number of properties stored in the object.
1326 index -= map()->inobject_properties();
1327 ASSERT(index < 0);
1328 int offset = map()->instance_size() + (index * kPointerSize);
1329 return READ_FIELD(this, offset);
1330}
1331
1332
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001333Object* JSObject::InObjectPropertyAtPut(int index,
1334 Object* value,
1335 WriteBarrierMode mode) {
1336 // Adjust for the number of properties stored in the object.
1337 index -= map()->inobject_properties();
1338 ASSERT(index < 0);
1339 int offset = map()->instance_size() + (index * kPointerSize);
1340 WRITE_FIELD(this, offset, value);
1341 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1342 return value;
1343}
1344
1345
1346
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001347void JSObject::InitializeBody(int object_size, Object* value) {
1348 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001349 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001350 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001351 }
1352}
1353
1354
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001355bool JSObject::HasFastProperties() {
1356 return !properties()->IsDictionary();
1357}
1358
1359
1360int JSObject::MaxFastProperties() {
1361 // Allow extra fast properties if the object has more than
1362 // kMaxFastProperties in-object properties. When this is the case,
1363 // it is very unlikely that the object is being used as a dictionary
1364 // and there is a good chance that allowing more map transitions
1365 // will be worth it.
1366 return Max(map()->inobject_properties(), kMaxFastProperties);
1367}
1368
1369
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001371 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001372 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001373 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001374 }
1375}
1376
1377
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001378bool Object::ToArrayIndex(uint32_t* index) {
1379 if (IsSmi()) {
1380 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381 if (value < 0) return false;
1382 *index = value;
1383 return true;
1384 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001385 if (IsHeapNumber()) {
1386 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001387 uint32_t uint_value = static_cast<uint32_t>(value);
1388 if (value == static_cast<double>(uint_value)) {
1389 *index = uint_value;
1390 return true;
1391 }
1392 }
1393 return false;
1394}
1395
1396
1397bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1398 if (!this->IsJSValue()) return false;
1399
1400 JSValue* js_value = JSValue::cast(this);
1401 if (!js_value->value()->IsString()) return false;
1402
1403 String* str = String::cast(js_value->value());
1404 if (index >= (uint32_t)str->length()) return false;
1405
1406 return true;
1407}
1408
1409
1410Object* FixedArray::get(int index) {
1411 ASSERT(index >= 0 && index < this->length());
1412 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1413}
1414
1415
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001416void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001417 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001418 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1419 int offset = kHeaderSize + index * kPointerSize;
1420 WRITE_FIELD(this, offset, value);
1421}
1422
1423
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001424void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001425 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426 ASSERT(index >= 0 && index < this->length());
1427 int offset = kHeaderSize + index * kPointerSize;
1428 WRITE_FIELD(this, offset, value);
1429 WRITE_BARRIER(this, offset);
1430}
1431
1432
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001433WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001434 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1435 return UPDATE_WRITE_BARRIER;
1436}
1437
1438
1439void FixedArray::set(int index,
1440 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001441 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001442 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443 ASSERT(index >= 0 && index < this->length());
1444 int offset = kHeaderSize + index * kPointerSize;
1445 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001446 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447}
1448
1449
1450void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001451 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001453 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001454 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1455}
1456
1457
1458void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001459 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460 ASSERT(index >= 0 && index < this->length());
1461 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1462 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1463 Heap::undefined_value());
1464}
1465
1466
ager@chromium.org236ad962008-09-25 09:45:57 +00001467void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001468 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001469 ASSERT(index >= 0 && index < this->length());
1470 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1471 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1472}
1473
1474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001476 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477 ASSERT(index >= 0 && index < this->length());
1478 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1479 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1480}
1481
1482
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001483void FixedArray::set_unchecked(int index, Smi* value) {
1484 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1485 int offset = kHeaderSize + index * kPointerSize;
1486 WRITE_FIELD(this, offset, value);
1487}
1488
1489
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001490void FixedArray::set_unchecked(int index,
1491 Object* value,
1492 WriteBarrierMode mode) {
1493 int offset = kHeaderSize + index * kPointerSize;
1494 WRITE_FIELD(this, offset, value);
1495 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1496}
1497
1498
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001499void FixedArray::set_null_unchecked(int index) {
1500 ASSERT(index >= 0 && index < this->length());
1501 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1502 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1503}
1504
1505
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001506Object** FixedArray::data_start() {
1507 return HeapObject::RawField(this, kHeaderSize);
1508}
1509
1510
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001511bool DescriptorArray::IsEmpty() {
1512 ASSERT(this == Heap::empty_descriptor_array() ||
1513 this->length() > 2);
1514 return this == Heap::empty_descriptor_array();
1515}
1516
1517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001518void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1519 Object* tmp = array->get(first);
1520 fast_set(array, first, array->get(second));
1521 fast_set(array, second, tmp);
1522}
1523
1524
1525int DescriptorArray::Search(String* name) {
1526 SLOW_ASSERT(IsSortedNoDuplicates());
1527
1528 // Check for empty descriptor array.
1529 int nof = number_of_descriptors();
1530 if (nof == 0) return kNotFound;
1531
1532 // Fast case: do linear search for small arrays.
1533 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001534 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001535 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001536 }
1537
1538 // Slow case: perform binary search.
1539 return BinarySearch(name, 0, nof - 1);
1540}
1541
1542
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001543int DescriptorArray::SearchWithCache(String* name) {
1544 int number = DescriptorLookupCache::Lookup(this, name);
1545 if (number == DescriptorLookupCache::kAbsent) {
1546 number = Search(name);
1547 DescriptorLookupCache::Update(this, name, number);
1548 }
1549 return number;
1550}
1551
1552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553String* DescriptorArray::GetKey(int descriptor_number) {
1554 ASSERT(descriptor_number < number_of_descriptors());
1555 return String::cast(get(ToKeyIndex(descriptor_number)));
1556}
1557
1558
1559Object* DescriptorArray::GetValue(int descriptor_number) {
1560 ASSERT(descriptor_number < number_of_descriptors());
1561 return GetContentArray()->get(ToValueIndex(descriptor_number));
1562}
1563
1564
1565Smi* DescriptorArray::GetDetails(int descriptor_number) {
1566 ASSERT(descriptor_number < number_of_descriptors());
1567 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1568}
1569
1570
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001571PropertyType DescriptorArray::GetType(int descriptor_number) {
1572 ASSERT(descriptor_number < number_of_descriptors());
1573 return PropertyDetails(GetDetails(descriptor_number)).type();
1574}
1575
1576
1577int DescriptorArray::GetFieldIndex(int descriptor_number) {
1578 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1579}
1580
1581
1582JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1583 return JSFunction::cast(GetValue(descriptor_number));
1584}
1585
1586
1587Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1588 ASSERT(GetType(descriptor_number) == CALLBACKS);
1589 return GetValue(descriptor_number);
1590}
1591
1592
1593AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1594 ASSERT(GetType(descriptor_number) == CALLBACKS);
1595 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1596 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1597}
1598
1599
1600bool DescriptorArray::IsProperty(int descriptor_number) {
1601 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1602}
1603
1604
1605bool DescriptorArray::IsTransition(int descriptor_number) {
1606 PropertyType t = GetType(descriptor_number);
1607 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1608}
1609
1610
1611bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1612 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1613}
1614
1615
1616bool DescriptorArray::IsDontEnum(int descriptor_number) {
1617 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1618}
1619
1620
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001621void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1622 desc->Init(GetKey(descriptor_number),
1623 GetValue(descriptor_number),
1624 GetDetails(descriptor_number));
1625}
1626
1627
1628void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1629 // Range check.
1630 ASSERT(descriptor_number < number_of_descriptors());
1631
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001632 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1634 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1635
1636 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1637 FixedArray* content_array = GetContentArray();
1638 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1639 fast_set(content_array, ToDetailsIndex(descriptor_number),
1640 desc->GetDetails().AsSmi());
1641}
1642
1643
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001644void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1645 Descriptor desc;
1646 src->Get(src_index, &desc);
1647 Set(index, &desc);
1648}
1649
1650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651void DescriptorArray::Swap(int first, int second) {
1652 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1653 FixedArray* content_array = GetContentArray();
1654 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1655 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1656}
1657
1658
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001659bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001660 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001661 if (!max_index_object->IsSmi()) return false;
1662 return 0 !=
1663 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1664}
1665
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001666uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001668 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669 if (!max_index_object->IsSmi()) return 0;
1670 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1671 return value >> kRequiresSlowElementsTagSize;
1672}
1673
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001674void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001675 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001676}
1677
1678
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001679// ------------------------------------
1680// Cast operations
1681
1682
1683CAST_ACCESSOR(FixedArray)
1684CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001685CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001686CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001687CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001688CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001689CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001690CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691CAST_ACCESSOR(String)
1692CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001693CAST_ACCESSOR(SeqAsciiString)
1694CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696CAST_ACCESSOR(ExternalString)
1697CAST_ACCESSOR(ExternalAsciiString)
1698CAST_ACCESSOR(ExternalTwoByteString)
1699CAST_ACCESSOR(JSObject)
1700CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701CAST_ACCESSOR(HeapObject)
1702CAST_ACCESSOR(HeapNumber)
1703CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001704CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705CAST_ACCESSOR(SharedFunctionInfo)
1706CAST_ACCESSOR(Map)
1707CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001708CAST_ACCESSOR(GlobalObject)
1709CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710CAST_ACCESSOR(JSGlobalObject)
1711CAST_ACCESSOR(JSBuiltinsObject)
1712CAST_ACCESSOR(Code)
1713CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001714CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715CAST_ACCESSOR(Proxy)
1716CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001717CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001718CAST_ACCESSOR(ExternalArray)
1719CAST_ACCESSOR(ExternalByteArray)
1720CAST_ACCESSOR(ExternalUnsignedByteArray)
1721CAST_ACCESSOR(ExternalShortArray)
1722CAST_ACCESSOR(ExternalUnsignedShortArray)
1723CAST_ACCESSOR(ExternalIntArray)
1724CAST_ACCESSOR(ExternalUnsignedIntArray)
1725CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726CAST_ACCESSOR(Struct)
1727
1728
1729#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1730 STRUCT_LIST(MAKE_STRUCT_CAST)
1731#undef MAKE_STRUCT_CAST
1732
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001733
1734template <typename Shape, typename Key>
1735HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736 ASSERT(obj->IsHashTable());
1737 return reinterpret_cast<HashTable*>(obj);
1738}
1739
1740
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001741SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1742SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1743
1744INT_ACCESSORS(PixelArray, length, kLengthOffset)
1745INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001746
1747
ager@chromium.orgac091b72010-05-05 07:34:42 +00001748SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001749
1750
1751uint32_t String::hash_field() {
1752 return READ_UINT32_FIELD(this, kHashFieldOffset);
1753}
1754
1755
1756void String::set_hash_field(uint32_t value) {
1757 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001758#if V8_HOST_ARCH_64_BIT
1759 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1760#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001761}
1762
1763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001764bool String::Equals(String* other) {
1765 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001766 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1767 return false;
1768 }
1769 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001770}
1771
1772
lrn@chromium.org303ada72010-10-27 09:33:13 +00001773MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001774 if (!StringShape(this).IsCons()) return this;
1775 ConsString* cons = ConsString::cast(this);
1776 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001777 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778}
1779
1780
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001781String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001782 MaybeObject* flat = TryFlatten(pretenure);
1783 Object* successfully_flattened;
1784 if (flat->ToObject(&successfully_flattened)) {
1785 return String::cast(successfully_flattened);
1786 }
1787 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001788}
1789
1790
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001791uint16_t String::Get(int index) {
1792 ASSERT(index >= 0 && index < length());
1793 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001794 case kSeqStringTag | kAsciiStringTag:
1795 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1796 case kSeqStringTag | kTwoByteStringTag:
1797 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1798 case kConsStringTag | kAsciiStringTag:
1799 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001801 case kExternalStringTag | kAsciiStringTag:
1802 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1803 case kExternalStringTag | kTwoByteStringTag:
1804 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 default:
1806 break;
1807 }
1808
1809 UNREACHABLE();
1810 return 0;
1811}
1812
1813
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001814void String::Set(int index, uint16_t value) {
1815 ASSERT(index >= 0 && index < length());
1816 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817
ager@chromium.org5ec48922009-05-05 07:25:34 +00001818 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001819 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1820 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001821}
1822
1823
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001824bool String::IsFlat() {
1825 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001826 case kConsStringTag: {
1827 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001828 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001829 return second->length() == 0;
1830 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001831 default:
1832 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833 }
1834}
1835
1836
ager@chromium.org7c537e22008-10-16 08:43:32 +00001837uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838 ASSERT(index >= 0 && index < length());
1839 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1840}
1841
1842
ager@chromium.org7c537e22008-10-16 08:43:32 +00001843void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001844 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1845 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1846 static_cast<byte>(value));
1847}
1848
1849
ager@chromium.org7c537e22008-10-16 08:43:32 +00001850Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 return FIELD_ADDR(this, kHeaderSize);
1852}
1853
1854
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001855char* SeqAsciiString::GetChars() {
1856 return reinterpret_cast<char*>(GetCharsAddress());
1857}
1858
1859
ager@chromium.org7c537e22008-10-16 08:43:32 +00001860Address SeqTwoByteString::GetCharsAddress() {
1861 return FIELD_ADDR(this, kHeaderSize);
1862}
1863
1864
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001865uc16* SeqTwoByteString::GetChars() {
1866 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1867}
1868
1869
ager@chromium.org7c537e22008-10-16 08:43:32 +00001870uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001871 ASSERT(index >= 0 && index < length());
1872 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1873}
1874
1875
ager@chromium.org7c537e22008-10-16 08:43:32 +00001876void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877 ASSERT(index >= 0 && index < length());
1878 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1879}
1880
1881
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001882int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001883 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884}
1885
1886
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001887int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001888 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001889}
1890
1891
ager@chromium.org870a0b62008-11-04 11:43:05 +00001892String* ConsString::first() {
1893 return String::cast(READ_FIELD(this, kFirstOffset));
1894}
1895
1896
1897Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001898 return READ_FIELD(this, kFirstOffset);
1899}
1900
1901
ager@chromium.org870a0b62008-11-04 11:43:05 +00001902void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001903 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001904 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905}
1906
1907
ager@chromium.org870a0b62008-11-04 11:43:05 +00001908String* ConsString::second() {
1909 return String::cast(READ_FIELD(this, kSecondOffset));
1910}
1911
1912
1913Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001914 return READ_FIELD(this, kSecondOffset);
1915}
1916
1917
ager@chromium.org870a0b62008-11-04 11:43:05 +00001918void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001919 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001920 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001921}
1922
1923
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1925 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1926}
1927
1928
1929void ExternalAsciiString::set_resource(
1930 ExternalAsciiString::Resource* resource) {
1931 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1932}
1933
1934
1935ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1936 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1937}
1938
1939
1940void ExternalTwoByteString::set_resource(
1941 ExternalTwoByteString::Resource* resource) {
1942 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1943}
1944
1945
ager@chromium.orgac091b72010-05-05 07:34:42 +00001946void JSFunctionResultCache::MakeZeroSize() {
1947 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1948 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1949}
1950
1951
1952void JSFunctionResultCache::Clear() {
1953 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1954 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001955 MemsetPointer(entries_start,
1956 Heap::the_hole_value(),
1957 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001958 MakeZeroSize();
1959}
1960
1961
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001962byte ByteArray::get(int index) {
1963 ASSERT(index >= 0 && index < this->length());
1964 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1965}
1966
1967
1968void ByteArray::set(int index, byte value) {
1969 ASSERT(index >= 0 && index < this->length());
1970 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1971}
1972
1973
1974int ByteArray::get_int(int index) {
1975 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1976 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1977}
1978
1979
1980ByteArray* ByteArray::FromDataStartAddress(Address address) {
1981 ASSERT_TAG_ALIGNED(address);
1982 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1983}
1984
1985
1986Address ByteArray::GetDataStartAddress() {
1987 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1988}
1989
1990
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001991uint8_t* PixelArray::external_pointer() {
1992 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1993 return reinterpret_cast<uint8_t*>(ptr);
1994}
1995
1996
1997void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1998 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1999 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2000}
2001
2002
2003uint8_t PixelArray::get(int index) {
2004 ASSERT((index >= 0) && (index < this->length()));
2005 uint8_t* ptr = external_pointer();
2006 return ptr[index];
2007}
2008
2009
2010void PixelArray::set(int index, uint8_t value) {
2011 ASSERT((index >= 0) && (index < this->length()));
2012 uint8_t* ptr = external_pointer();
2013 ptr[index] = value;
2014}
2015
2016
ager@chromium.org3811b432009-10-28 14:53:37 +00002017void* ExternalArray::external_pointer() {
2018 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2019 return reinterpret_cast<void*>(ptr);
2020}
2021
2022
2023void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2024 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2025 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2026}
2027
2028
2029int8_t ExternalByteArray::get(int index) {
2030 ASSERT((index >= 0) && (index < this->length()));
2031 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2032 return ptr[index];
2033}
2034
2035
2036void ExternalByteArray::set(int index, int8_t value) {
2037 ASSERT((index >= 0) && (index < this->length()));
2038 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2039 ptr[index] = value;
2040}
2041
2042
2043uint8_t ExternalUnsignedByteArray::get(int index) {
2044 ASSERT((index >= 0) && (index < this->length()));
2045 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2046 return ptr[index];
2047}
2048
2049
2050void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2051 ASSERT((index >= 0) && (index < this->length()));
2052 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2053 ptr[index] = value;
2054}
2055
2056
2057int16_t ExternalShortArray::get(int index) {
2058 ASSERT((index >= 0) && (index < this->length()));
2059 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2060 return ptr[index];
2061}
2062
2063
2064void ExternalShortArray::set(int index, int16_t value) {
2065 ASSERT((index >= 0) && (index < this->length()));
2066 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2067 ptr[index] = value;
2068}
2069
2070
2071uint16_t ExternalUnsignedShortArray::get(int index) {
2072 ASSERT((index >= 0) && (index < this->length()));
2073 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2074 return ptr[index];
2075}
2076
2077
2078void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2079 ASSERT((index >= 0) && (index < this->length()));
2080 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2081 ptr[index] = value;
2082}
2083
2084
2085int32_t ExternalIntArray::get(int index) {
2086 ASSERT((index >= 0) && (index < this->length()));
2087 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2088 return ptr[index];
2089}
2090
2091
2092void ExternalIntArray::set(int index, int32_t value) {
2093 ASSERT((index >= 0) && (index < this->length()));
2094 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2095 ptr[index] = value;
2096}
2097
2098
2099uint32_t ExternalUnsignedIntArray::get(int index) {
2100 ASSERT((index >= 0) && (index < this->length()));
2101 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2102 return ptr[index];
2103}
2104
2105
2106void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2107 ASSERT((index >= 0) && (index < this->length()));
2108 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2109 ptr[index] = value;
2110}
2111
2112
2113float ExternalFloatArray::get(int index) {
2114 ASSERT((index >= 0) && (index < this->length()));
2115 float* ptr = static_cast<float*>(external_pointer());
2116 return ptr[index];
2117}
2118
2119
2120void ExternalFloatArray::set(int index, float value) {
2121 ASSERT((index >= 0) && (index < this->length()));
2122 float* ptr = static_cast<float*>(external_pointer());
2123 ptr[index] = value;
2124}
2125
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002126
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002127int Map::visitor_id() {
2128 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2129}
2130
2131
2132void Map::set_visitor_id(int id) {
2133 ASSERT(0 <= id && id < 256);
2134 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2135}
2136
ager@chromium.org3811b432009-10-28 14:53:37 +00002137
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002139 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2140}
2141
2142
2143int Map::inobject_properties() {
2144 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145}
2146
2147
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002148int Map::pre_allocated_property_fields() {
2149 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2150}
2151
2152
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002154 int instance_size = map->instance_size();
2155 if (instance_size != kVariableSizeSentinel) return instance_size;
2156 // We can ignore the "symbol" bit becase it is only set for symbols
2157 // and implies a string type.
2158 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002159 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002161 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002162 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002163 if (instance_type == ASCII_STRING_TYPE) {
2164 return SeqAsciiString::SizeFor(
2165 reinterpret_cast<SeqAsciiString*>(this)->length());
2166 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002167 if (instance_type == BYTE_ARRAY_TYPE) {
2168 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2169 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002170 if (instance_type == STRING_TYPE) {
2171 return SeqTwoByteString::SizeFor(
2172 reinterpret_cast<SeqTwoByteString*>(this)->length());
2173 }
2174 ASSERT(instance_type == CODE_TYPE);
2175 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176}
2177
2178
2179void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002180 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002181 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002182 ASSERT(0 <= value && value < 256);
2183 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2184}
2185
2186
ager@chromium.org7c537e22008-10-16 08:43:32 +00002187void Map::set_inobject_properties(int value) {
2188 ASSERT(0 <= value && value < 256);
2189 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2190}
2191
2192
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002193void Map::set_pre_allocated_property_fields(int value) {
2194 ASSERT(0 <= value && value < 256);
2195 WRITE_BYTE_FIELD(this,
2196 kPreAllocatedPropertyFieldsOffset,
2197 static_cast<byte>(value));
2198}
2199
2200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201InstanceType Map::instance_type() {
2202 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2203}
2204
2205
2206void Map::set_instance_type(InstanceType value) {
2207 ASSERT(0 <= value && value < 256);
2208 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2209}
2210
2211
2212int Map::unused_property_fields() {
2213 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2214}
2215
2216
2217void Map::set_unused_property_fields(int value) {
2218 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2219}
2220
2221
2222byte Map::bit_field() {
2223 return READ_BYTE_FIELD(this, kBitFieldOffset);
2224}
2225
2226
2227void Map::set_bit_field(byte value) {
2228 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2229}
2230
2231
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002232byte Map::bit_field2() {
2233 return READ_BYTE_FIELD(this, kBitField2Offset);
2234}
2235
2236
2237void Map::set_bit_field2(byte value) {
2238 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2239}
2240
2241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242void Map::set_non_instance_prototype(bool value) {
2243 if (value) {
2244 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2245 } else {
2246 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2247 }
2248}
2249
2250
2251bool Map::has_non_instance_prototype() {
2252 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2253}
2254
2255
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002256void Map::set_function_with_prototype(bool value) {
2257 if (value) {
2258 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2259 } else {
2260 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2261 }
2262}
2263
2264
2265bool Map::function_with_prototype() {
2266 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2267}
2268
2269
ager@chromium.org870a0b62008-11-04 11:43:05 +00002270void Map::set_is_access_check_needed(bool access_check_needed) {
2271 if (access_check_needed) {
2272 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2273 } else {
2274 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2275 }
2276}
2277
2278
2279bool Map::is_access_check_needed() {
2280 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2281}
2282
2283
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002284void Map::set_is_extensible(bool value) {
2285 if (value) {
2286 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2287 } else {
2288 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2289 }
2290}
2291
2292bool Map::is_extensible() {
2293 return ((1 << kIsExtensible) & bit_field2()) != 0;
2294}
2295
2296
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002297void Map::set_attached_to_shared_function_info(bool value) {
2298 if (value) {
2299 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2300 } else {
2301 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2302 }
2303}
2304
2305bool Map::attached_to_shared_function_info() {
2306 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2307}
2308
2309
2310void Map::set_is_shared(bool value) {
2311 if (value) {
2312 set_bit_field2(bit_field2() | (1 << kIsShared));
2313 } else {
2314 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2315 }
2316}
2317
2318bool Map::is_shared() {
2319 return ((1 << kIsShared) & bit_field2()) != 0;
2320}
2321
2322
2323JSFunction* Map::unchecked_constructor() {
2324 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2325}
2326
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002328Code::Flags Code::flags() {
2329 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2330}
2331
2332
2333void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002334 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002336 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2337 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338 ExtractArgumentsCountFromFlags(flags) >= 0);
2339 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2340}
2341
2342
2343Code::Kind Code::kind() {
2344 return ExtractKindFromFlags(flags());
2345}
2346
2347
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002348InLoopFlag Code::ic_in_loop() {
2349 return ExtractICInLoopFromFlags(flags());
2350}
2351
2352
kasper.lund7276f142008-07-30 08:49:36 +00002353InlineCacheState Code::ic_state() {
2354 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002355 // Only allow uninitialized or debugger states for non-IC code
2356 // objects. This is used in the debugger to determine whether or not
2357 // a call to code object has been replaced with a debug break call.
2358 ASSERT(is_inline_cache_stub() ||
2359 result == UNINITIALIZED ||
2360 result == DEBUG_BREAK ||
2361 result == DEBUG_PREPARE_STEP_IN);
2362 return result;
2363}
2364
2365
2366PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002367 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368 return ExtractTypeFromFlags(flags());
2369}
2370
2371
2372int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002373 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374 return ExtractArgumentsCountFromFlags(flags());
2375}
2376
2377
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002378int Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002379 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002380 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002381}
2382
2383
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002384void Code::set_major_key(int major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002385 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002386 ASSERT(0 <= major && major < 256);
2387 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388}
2389
2390
2391bool Code::is_inline_cache_stub() {
2392 Kind kind = this->kind();
2393 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2394}
2395
2396
2397Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002398 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002399 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002401 int argc,
2402 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 // Compute the bit mask.
2404 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002405 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002406 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407 bits |= type << kFlagsTypeShift;
2408 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002409 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410 // Cast to flags and validate result before returning it.
2411 Flags result = static_cast<Flags>(bits);
2412 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002413 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002414 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002415 ASSERT(ExtractTypeFromFlags(result) == type);
2416 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2417 return result;
2418}
2419
2420
2421Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2422 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002423 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002424 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002426 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427}
2428
2429
2430Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2431 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2432 return static_cast<Kind>(bits);
2433}
2434
2435
kasper.lund7276f142008-07-30 08:49:36 +00002436InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2437 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002438 return static_cast<InlineCacheState>(bits);
2439}
2440
2441
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002442InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2443 int bits = (flags & kFlagsICInLoopMask);
2444 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2445}
2446
2447
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002448PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2449 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2450 return static_cast<PropertyType>(bits);
2451}
2452
2453
2454int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2455 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2456}
2457
2458
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002459InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2460 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2461 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2462}
2463
2464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2466 int bits = flags & ~kFlagsTypeMask;
2467 return static_cast<Flags>(bits);
2468}
2469
2470
ager@chromium.org8bb60582008-12-11 12:02:20 +00002471Code* Code::GetCodeFromTargetAddress(Address address) {
2472 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2473 // GetCodeFromTargetAddress might be called when marking objects during mark
2474 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2475 // Code::cast. Code::cast does not work when the object's map is
2476 // marked.
2477 Code* result = reinterpret_cast<Code*>(code);
2478 return result;
2479}
2480
2481
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002482Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2483 return HeapObject::
2484 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2485}
2486
2487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002488Object* Map::prototype() {
2489 return READ_FIELD(this, kPrototypeOffset);
2490}
2491
2492
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002493void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002494 ASSERT(value->IsNull() || value->IsJSObject());
2495 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002496 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497}
2498
2499
lrn@chromium.org303ada72010-10-27 09:33:13 +00002500MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002501 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002502 Object* obj;
2503 { MaybeObject* maybe_obj = CopyDropTransitions();
2504 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2505 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002506 Map* new_map = Map::cast(obj);
2507 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002508 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002509 return new_map;
2510}
2511
2512
lrn@chromium.org303ada72010-10-27 09:33:13 +00002513MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002514 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002515 Object* obj;
2516 { MaybeObject* maybe_obj = CopyDropTransitions();
2517 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2518 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002519 Map* new_map = Map::cast(obj);
2520 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002521 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002522 return new_map;
2523}
2524
2525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002526ACCESSORS(Map, instance_descriptors, DescriptorArray,
2527 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002528ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529ACCESSORS(Map, constructor, Object, kConstructorOffset)
2530
2531ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2532ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2533
2534ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2535ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002536ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002537
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002538ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539
2540ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2541ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2542ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2543ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2544ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002545ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546
2547ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2548ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2549ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2550
2551ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2552ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2553ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2554ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2555ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2556ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2557
2558ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2559ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2560
2561ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2562ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2563
2564ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2565ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002566ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2567 kPropertyAccessorsOffset)
2568ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2569 kPrototypeTemplateOffset)
2570ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2571ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2572 kNamedPropertyHandlerOffset)
2573ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2574 kIndexedPropertyHandlerOffset)
2575ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2576 kInstanceTemplateOffset)
2577ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2578ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2580 kInstanceCallHandlerOffset)
2581ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2582 kAccessCheckInfoOffset)
2583ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2584
2585ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002586ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2587 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002588
2589ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2590ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2591
2592ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2593
2594ACCESSORS(Script, source, Object, kSourceOffset)
2595ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002596ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2598ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002599ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002600ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002601ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2602ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002603ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002604ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002605ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002606ACCESSORS(Script, eval_from_instructions_offset, Smi,
2607 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002609#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2611ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2612ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2613ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2614
2615ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2616ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2617ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2618ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002619#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002620
2621ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002622ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002623ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2625 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002626ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002627ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2628ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002629ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002630ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2631 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632
2633BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2634 kHiddenPrototypeBit)
2635BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2636BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2637 kNeedsAccessCheckBit)
2638BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2639 kIsExpressionBit)
2640BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2641 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002642BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002643 has_only_simple_this_property_assignments,
2644 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002645BOOL_ACCESSORS(SharedFunctionInfo,
2646 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002647 try_full_codegen,
2648 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002649BOOL_ACCESSORS(SharedFunctionInfo,
2650 compiler_hints,
2651 allows_lazy_compilation,
2652 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002654
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002655#if V8_HOST_ARCH_32_BIT
2656SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2657SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002658 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002659SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002660 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002661SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2662SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002663 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002664SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2665SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002666 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002667SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002668 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002669SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002670 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002671#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002673#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2674 int holder::name() { \
2675 int value = READ_INT_FIELD(this, offset); \
2676 ASSERT(kHeapObjectTag == 1); \
2677 ASSERT((value & kHeapObjectTag) == 0); \
2678 return value >> 1; \
2679 } \
2680 void holder::set_##name(int value) { \
2681 ASSERT(kHeapObjectTag == 1); \
2682 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2683 (value & 0xC0000000) == 0x000000000); \
2684 WRITE_INT_FIELD(this, \
2685 offset, \
2686 (value << 1) & ~kHeapObjectTag); \
2687 }
2688
2689#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2690 INT_ACCESSORS(holder, name, offset)
2691
2692
2693
2694PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2695PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2696 kFormalParameterCountOffset)
2697
2698PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2699 kExpectedNofPropertiesOffset)
2700PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2701
2702PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2703 kStartPositionAndTypeOffset)
2704PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2705
2706PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2707 kFunctionTokenPositionOffset)
2708PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2709 kCompilerHintsOffset)
2710
2711PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2712 kThisPropertyAssignmentsCountOffset)
2713#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002715
2716int SharedFunctionInfo::construction_count() {
2717 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2718}
2719
2720
2721void SharedFunctionInfo::set_construction_count(int value) {
2722 ASSERT(0 <= value && value < 256);
2723 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2724}
2725
2726
2727bool SharedFunctionInfo::live_objects_may_exist() {
2728 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2729}
2730
2731
2732void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2733 if (value) {
2734 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2735 } else {
2736 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2737 }
2738}
2739
2740
2741bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2742 return initial_map() != Heap::undefined_value();
2743}
2744
2745
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002746ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2747ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2748
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002749bool Script::HasValidSource() {
2750 Object* src = this->source();
2751 if (!src->IsString()) return true;
2752 String* src_str = String::cast(src);
2753 if (!StringShape(src_str).IsExternal()) return true;
2754 if (src_str->IsAsciiRepresentation()) {
2755 return ExternalAsciiString::cast(src)->resource() != NULL;
2756 } else if (src_str->IsTwoByteRepresentation()) {
2757 return ExternalTwoByteString::cast(src)->resource() != NULL;
2758 }
2759 return true;
2760}
2761
2762
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002763void SharedFunctionInfo::DontAdaptArguments() {
2764 ASSERT(code()->kind() == Code::BUILTIN);
2765 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2766}
2767
2768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002769int SharedFunctionInfo::start_position() {
2770 return start_position_and_type() >> kStartPositionShift;
2771}
2772
2773
2774void SharedFunctionInfo::set_start_position(int start_position) {
2775 set_start_position_and_type((start_position << kStartPositionShift)
2776 | (start_position_and_type() & ~kStartPositionMask));
2777}
2778
2779
2780Code* SharedFunctionInfo::code() {
2781 return Code::cast(READ_FIELD(this, kCodeOffset));
2782}
2783
2784
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002785Code* SharedFunctionInfo::unchecked_code() {
2786 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2787}
2788
2789
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002790void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002792 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002793}
2794
2795
ager@chromium.orgb5737492010-07-15 09:29:43 +00002796SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2797 return reinterpret_cast<SerializedScopeInfo*>(
2798 READ_FIELD(this, kScopeInfoOffset));
2799}
2800
2801
2802void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2803 WriteBarrierMode mode) {
2804 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2805 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2806}
2807
2808
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002810 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002811}
2812
2813
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002814bool SharedFunctionInfo::IsApiFunction() {
2815 return function_data()->IsFunctionTemplateInfo();
2816}
2817
2818
2819FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2820 ASSERT(IsApiFunction());
2821 return FunctionTemplateInfo::cast(function_data());
2822}
2823
2824
2825bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002826 return function_data()->IsSmi();
2827}
2828
2829
2830int SharedFunctionInfo::custom_call_generator_id() {
2831 ASSERT(HasCustomCallGenerator());
2832 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002833}
2834
2835
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002836int SharedFunctionInfo::code_age() {
2837 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2838}
2839
2840
2841void SharedFunctionInfo::set_code_age(int code_age) {
2842 set_compiler_hints(compiler_hints() |
2843 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2844}
2845
2846
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002847bool JSFunction::IsBuiltin() {
2848 return context()->global()->IsJSBuiltinsObject();
2849}
2850
2851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002853 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854}
2855
2856
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002857Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002858 return reinterpret_cast<Code*>(
2859 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002860}
2861
2862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002864 // Skip the write barrier because code is never in new space.
2865 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002866 Address entry = value->entry();
2867 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002868}
2869
2870
2871Context* JSFunction::context() {
2872 return Context::cast(READ_FIELD(this, kContextOffset));
2873}
2874
2875
2876Object* JSFunction::unchecked_context() {
2877 return READ_FIELD(this, kContextOffset);
2878}
2879
2880
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002881SharedFunctionInfo* JSFunction::unchecked_shared() {
2882 return reinterpret_cast<SharedFunctionInfo*>(
2883 READ_FIELD(this, kSharedFunctionInfoOffset));
2884}
2885
2886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002887void JSFunction::set_context(Object* value) {
2888 ASSERT(value == Heap::undefined_value() || value->IsContext());
2889 WRITE_FIELD(this, kContextOffset, value);
2890 WRITE_BARRIER(this, kContextOffset);
2891}
2892
2893ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2894 kPrototypeOrInitialMapOffset)
2895
2896
2897Map* JSFunction::initial_map() {
2898 return Map::cast(prototype_or_initial_map());
2899}
2900
2901
2902void JSFunction::set_initial_map(Map* value) {
2903 set_prototype_or_initial_map(value);
2904}
2905
2906
2907bool JSFunction::has_initial_map() {
2908 return prototype_or_initial_map()->IsMap();
2909}
2910
2911
2912bool JSFunction::has_instance_prototype() {
2913 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2914}
2915
2916
2917bool JSFunction::has_prototype() {
2918 return map()->has_non_instance_prototype() || has_instance_prototype();
2919}
2920
2921
2922Object* JSFunction::instance_prototype() {
2923 ASSERT(has_instance_prototype());
2924 if (has_initial_map()) return initial_map()->prototype();
2925 // When there is no initial map and the prototype is a JSObject, the
2926 // initial map field is used for the prototype field.
2927 return prototype_or_initial_map();
2928}
2929
2930
2931Object* JSFunction::prototype() {
2932 ASSERT(has_prototype());
2933 // If the function's prototype property has been set to a non-JSObject
2934 // value, that value is stored in the constructor field of the map.
2935 if (map()->has_non_instance_prototype()) return map()->constructor();
2936 return instance_prototype();
2937}
2938
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002939bool JSFunction::should_have_prototype() {
2940 return map()->function_with_prototype();
2941}
2942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943
2944bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002945 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002946}
2947
2948
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002949int JSFunction::NumberOfLiterals() {
2950 return literals()->length();
2951}
2952
2953
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002954Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2955 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002956 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957}
2958
2959
2960void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2961 Object* value) {
2962 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002963 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2964 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2965}
2966
2967
2968Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2969 ASSERT(0 <= id && id < kJSBuiltinsCount);
2970 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2971}
2972
2973
2974void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2975 Code* value) {
2976 ASSERT(0 <= id && id < kJSBuiltinsCount);
2977 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2978 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002979}
2980
2981
2982Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002983 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984}
2985
2986
2987void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002988 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002989}
2990
2991
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002992ACCESSORS(JSValue, value, Object, kValueOffset)
2993
2994
2995JSValue* JSValue::cast(Object* obj) {
2996 ASSERT(obj->IsJSValue());
2997 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2998 return reinterpret_cast<JSValue*>(obj);
2999}
3000
3001
3002INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003003ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004
3005
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006byte* Code::instruction_start() {
3007 return FIELD_ADDR(this, kHeaderSize);
3008}
3009
3010
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003011byte* Code::instruction_end() {
3012 return instruction_start() + instruction_size();
3013}
3014
3015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003016int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003017 return RoundUp(instruction_size(), kObjectAlignment);
3018}
3019
3020
3021ByteArray* Code::unchecked_relocation_info() {
3022 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003023}
3024
3025
3026byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003027 return unchecked_relocation_info()->GetDataStartAddress();
3028}
3029
3030
3031int Code::relocation_size() {
3032 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003033}
3034
3035
3036byte* Code::entry() {
3037 return instruction_start();
3038}
3039
3040
3041bool Code::contains(byte* pc) {
3042 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003043 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003044}
3045
3046
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003047ACCESSORS(JSArray, length, Object, kLengthOffset)
3048
3049
ager@chromium.org236ad962008-09-25 09:45:57 +00003050ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003051
3052
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003053JSRegExp::Type JSRegExp::TypeTag() {
3054 Object* data = this->data();
3055 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3056 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3057 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003058}
3059
3060
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003061int JSRegExp::CaptureCount() {
3062 switch (TypeTag()) {
3063 case ATOM:
3064 return 0;
3065 case IRREGEXP:
3066 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3067 default:
3068 UNREACHABLE();
3069 return -1;
3070 }
3071}
3072
3073
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003074JSRegExp::Flags JSRegExp::GetFlags() {
3075 ASSERT(this->data()->IsFixedArray());
3076 Object* data = this->data();
3077 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3078 return Flags(smi->value());
3079}
3080
3081
3082String* JSRegExp::Pattern() {
3083 ASSERT(this->data()->IsFixedArray());
3084 Object* data = this->data();
3085 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3086 return pattern;
3087}
3088
3089
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003090Object* JSRegExp::DataAt(int index) {
3091 ASSERT(TypeTag() != NOT_COMPILED);
3092 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003093}
3094
3095
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003096void JSRegExp::SetDataAt(int index, Object* value) {
3097 ASSERT(TypeTag() != NOT_COMPILED);
3098 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3099 FixedArray::cast(data())->set(index, value);
3100}
3101
3102
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003103JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003104 if (map()->has_fast_elements()) {
3105 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3106 elements()->map() == Heap::fixed_cow_array_map());
3107 return FAST_ELEMENTS;
3108 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003109 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003110 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003111 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3112 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003113 ASSERT(array->IsDictionary());
3114 return DICTIONARY_ELEMENTS;
3115 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003116 if (array->IsExternalArray()) {
3117 switch (array->map()->instance_type()) {
3118 case EXTERNAL_BYTE_ARRAY_TYPE:
3119 return EXTERNAL_BYTE_ELEMENTS;
3120 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3121 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3122 case EXTERNAL_SHORT_ARRAY_TYPE:
3123 return EXTERNAL_SHORT_ELEMENTS;
3124 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3125 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3126 case EXTERNAL_INT_ARRAY_TYPE:
3127 return EXTERNAL_INT_ELEMENTS;
3128 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3129 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3130 default:
3131 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3132 return EXTERNAL_FLOAT_ELEMENTS;
3133 }
3134 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003135 ASSERT(array->IsPixelArray());
3136 return PIXEL_ELEMENTS;
3137}
3138
3139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003140bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003141 return GetElementsKind() == FAST_ELEMENTS;
3142}
3143
3144
3145bool JSObject::HasDictionaryElements() {
3146 return GetElementsKind() == DICTIONARY_ELEMENTS;
3147}
3148
3149
3150bool JSObject::HasPixelElements() {
3151 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003152}
3153
3154
ager@chromium.org3811b432009-10-28 14:53:37 +00003155bool JSObject::HasExternalArrayElements() {
3156 return (HasExternalByteElements() ||
3157 HasExternalUnsignedByteElements() ||
3158 HasExternalShortElements() ||
3159 HasExternalUnsignedShortElements() ||
3160 HasExternalIntElements() ||
3161 HasExternalUnsignedIntElements() ||
3162 HasExternalFloatElements());
3163}
3164
3165
3166bool JSObject::HasExternalByteElements() {
3167 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3168}
3169
3170
3171bool JSObject::HasExternalUnsignedByteElements() {
3172 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3173}
3174
3175
3176bool JSObject::HasExternalShortElements() {
3177 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3178}
3179
3180
3181bool JSObject::HasExternalUnsignedShortElements() {
3182 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3183}
3184
3185
3186bool JSObject::HasExternalIntElements() {
3187 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3188}
3189
3190
3191bool JSObject::HasExternalUnsignedIntElements() {
3192 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3193}
3194
3195
3196bool JSObject::HasExternalFloatElements() {
3197 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3198}
3199
3200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003201bool JSObject::HasNamedInterceptor() {
3202 return map()->has_named_interceptor();
3203}
3204
3205
3206bool JSObject::HasIndexedInterceptor() {
3207 return map()->has_indexed_interceptor();
3208}
3209
3210
ager@chromium.org5c838252010-02-19 08:53:10 +00003211bool JSObject::AllowsSetElementsLength() {
3212 bool result = elements()->IsFixedArray();
3213 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3214 return result;
3215}
3216
3217
lrn@chromium.org303ada72010-10-27 09:33:13 +00003218MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003219 ASSERT(HasFastElements());
3220 FixedArray* elems = FixedArray::cast(elements());
3221 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003222 Object* writable_elems;
3223 { MaybeObject* maybe_writable_elems =
3224 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3225 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3226 return maybe_writable_elems;
3227 }
3228 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003229 set_elements(FixedArray::cast(writable_elems));
3230 Counters::cow_arrays_converted.Increment();
3231 return writable_elems;
3232}
3233
3234
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003235StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003237 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238}
3239
3240
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003241NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003242 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003243 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003244}
3245
3246
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003247bool String::IsHashFieldComputed(uint32_t field) {
3248 return (field & kHashNotComputedMask) == 0;
3249}
3250
3251
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003253 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
3257uint32_t String::Hash() {
3258 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003259 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003260 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003261 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003262 return ComputeAndSetHash();
3263}
3264
3265
ager@chromium.org7c537e22008-10-16 08:43:32 +00003266StringHasher::StringHasher(int length)
3267 : length_(length),
3268 raw_running_hash_(0),
3269 array_index_(0),
3270 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3271 is_first_char_(true),
3272 is_valid_(true) { }
3273
3274
3275bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003276 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003277}
3278
3279
3280void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003281 // Use the Jenkins one-at-a-time hash function to update the hash
3282 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003283 raw_running_hash_ += c;
3284 raw_running_hash_ += (raw_running_hash_ << 10);
3285 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003286 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003287 if (is_array_index_) {
3288 if (c < '0' || c > '9') {
3289 is_array_index_ = false;
3290 } else {
3291 int d = c - '0';
3292 if (is_first_char_) {
3293 is_first_char_ = false;
3294 if (c == '0' && length_ > 1) {
3295 is_array_index_ = false;
3296 return;
3297 }
3298 }
3299 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3300 is_array_index_ = false;
3301 } else {
3302 array_index_ = array_index_ * 10 + d;
3303 }
3304 }
3305 }
3306}
3307
3308
3309void StringHasher::AddCharacterNoIndex(uc32 c) {
3310 ASSERT(!is_array_index());
3311 raw_running_hash_ += c;
3312 raw_running_hash_ += (raw_running_hash_ << 10);
3313 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3314}
3315
3316
3317uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003318 // Get the calculated raw hash value and do some more bit ops to distribute
3319 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003320 uint32_t result = raw_running_hash_;
3321 result += (result << 3);
3322 result ^= (result >> 11);
3323 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003324 if (result == 0) {
3325 result = 27;
3326 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003327 return result;
3328}
3329
3330
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003332 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003333 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3334 return false;
3335 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003336 return SlowAsArrayIndex(index);
3337}
3338
3339
3340Object* JSObject::GetPrototype() {
3341 return JSObject::cast(this)->map()->prototype();
3342}
3343
3344
3345PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3346 return GetPropertyAttributeWithReceiver(this, key);
3347}
3348
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003349// TODO(504): this may be useful in other places too where JSGlobalProxy
3350// is used.
3351Object* JSObject::BypassGlobalProxy() {
3352 if (IsJSGlobalProxy()) {
3353 Object* proto = GetPrototype();
3354 if (proto->IsNull()) return Heap::undefined_value();
3355 ASSERT(proto->IsJSGlobalObject());
3356 return proto;
3357 }
3358 return this;
3359}
3360
3361
3362bool JSObject::HasHiddenPropertiesObject() {
3363 ASSERT(!IsJSGlobalProxy());
3364 return GetPropertyAttributePostInterceptor(this,
3365 Heap::hidden_symbol(),
3366 false) != ABSENT;
3367}
3368
3369
3370Object* JSObject::GetHiddenPropertiesObject() {
3371 ASSERT(!IsJSGlobalProxy());
3372 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003373 // You can't install a getter on a property indexed by the hidden symbol,
3374 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3375 // object.
3376 Object* result =
3377 GetLocalPropertyPostInterceptor(this,
3378 Heap::hidden_symbol(),
3379 &attributes)->ToObjectUnchecked();
3380 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003381}
3382
3383
lrn@chromium.org303ada72010-10-27 09:33:13 +00003384MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003385 ASSERT(!IsJSGlobalProxy());
3386 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3387 hidden_obj,
3388 DONT_ENUM);
3389}
3390
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391
3392bool JSObject::HasElement(uint32_t index) {
3393 return HasElementWithReceiver(this, index);
3394}
3395
3396
3397bool AccessorInfo::all_can_read() {
3398 return BooleanBit::get(flag(), kAllCanReadBit);
3399}
3400
3401
3402void AccessorInfo::set_all_can_read(bool value) {
3403 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3404}
3405
3406
3407bool AccessorInfo::all_can_write() {
3408 return BooleanBit::get(flag(), kAllCanWriteBit);
3409}
3410
3411
3412void AccessorInfo::set_all_can_write(bool value) {
3413 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3414}
3415
3416
ager@chromium.org870a0b62008-11-04 11:43:05 +00003417bool AccessorInfo::prohibits_overwriting() {
3418 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3419}
3420
3421
3422void AccessorInfo::set_prohibits_overwriting(bool value) {
3423 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3424}
3425
3426
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427PropertyAttributes AccessorInfo::property_attributes() {
3428 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3429}
3430
3431
3432void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3433 ASSERT(AttributesField::is_valid(attributes));
3434 int rest_value = flag()->value() & ~AttributesField::mask();
3435 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3436}
3437
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003438template<typename Shape, typename Key>
3439void Dictionary<Shape, Key>::SetEntry(int entry,
3440 Object* key,
3441 Object* value,
3442 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003443 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003444 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003445 AssertNoAllocation no_gc;
3446 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003447 FixedArray::set(index, key, mode);
3448 FixedArray::set(index+1, value, mode);
3449 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450}
3451
3452
3453void Map::ClearCodeCache() {
3454 // No write barrier is needed since empty_fixed_array is not in new space.
3455 // Please note this function is used during marking:
3456 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003457 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3458 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003459}
3460
3461
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003462void JSArray::EnsureSize(int required_size) {
3463 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003464 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003465 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3466 if (elts->length() < required_size) {
3467 // Doubling in size would be overkill, but leave some slack to avoid
3468 // constantly growing.
3469 Expand(required_size + (required_size >> 3));
3470 // It's a performance benefit to keep a frequently used array in new-space.
3471 } else if (!Heap::new_space()->Contains(elts) &&
3472 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3473 // Expand will allocate a new backing store in new space even if the size
3474 // we asked for isn't larger than what we had before.
3475 Expand(required_size);
3476 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003477}
3478
3479
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003480void JSArray::set_length(Smi* length) {
3481 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3482}
3483
3484
ager@chromium.org7c537e22008-10-16 08:43:32 +00003485void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003486 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003487 set_elements(storage);
3488}
3489
3490
lrn@chromium.org303ada72010-10-27 09:33:13 +00003491MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003492 if (length() == 0) return this;
3493 return Heap::CopyFixedArray(this);
3494}
3495
3496
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003497int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3498 return map->instance_size();
3499}
3500
3501
3502void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3503 v->VisitExternalReference(
3504 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3505}
3506
3507
3508template<typename StaticVisitor>
3509void Proxy::ProxyIterateBody() {
3510 StaticVisitor::VisitExternalReference(
3511 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3512}
3513
3514
3515void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3516 typedef v8::String::ExternalAsciiStringResource Resource;
3517 v->VisitExternalAsciiString(
3518 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3519}
3520
3521
3522template<typename StaticVisitor>
3523void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3524 typedef v8::String::ExternalAsciiStringResource Resource;
3525 StaticVisitor::VisitExternalAsciiString(
3526 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3527}
3528
3529
3530void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3531 typedef v8::String::ExternalStringResource Resource;
3532 v->VisitExternalTwoByteString(
3533 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3534}
3535
3536
3537template<typename StaticVisitor>
3538void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3539 typedef v8::String::ExternalStringResource Resource;
3540 StaticVisitor::VisitExternalTwoByteString(
3541 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3542}
3543
3544#define SLOT_ADDR(obj, offset) \
3545 reinterpret_cast<Object**>((obj)->address() + offset)
3546
3547template<int start_offset, int end_offset, int size>
3548void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3549 HeapObject* obj,
3550 ObjectVisitor* v) {
3551 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3552}
3553
3554
3555template<int start_offset>
3556void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3557 int object_size,
3558 ObjectVisitor* v) {
3559 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3560}
3561
3562#undef SLOT_ADDR
3563
3564
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003565#undef CAST_ACCESSOR
3566#undef INT_ACCESSORS
3567#undef SMI_ACCESSORS
3568#undef ACCESSORS
3569#undef FIELD_ADDR
3570#undef READ_FIELD
3571#undef WRITE_FIELD
3572#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003573#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003574#undef READ_MEMADDR_FIELD
3575#undef WRITE_MEMADDR_FIELD
3576#undef READ_DOUBLE_FIELD
3577#undef WRITE_DOUBLE_FIELD
3578#undef READ_INT_FIELD
3579#undef WRITE_INT_FIELD
3580#undef READ_SHORT_FIELD
3581#undef WRITE_SHORT_FIELD
3582#undef READ_BYTE_FIELD
3583#undef WRITE_BYTE_FIELD
3584
3585
3586} } // namespace v8::internal
3587
3588#endif // V8_OBJECTS_INL_H_