blob: 4d210172b8b1bc310b738fa326e338c61da3a46e [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));
1955 MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
1956 MakeZeroSize();
1957}
1958
1959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001960byte ByteArray::get(int index) {
1961 ASSERT(index >= 0 && index < this->length());
1962 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1963}
1964
1965
1966void ByteArray::set(int index, byte value) {
1967 ASSERT(index >= 0 && index < this->length());
1968 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1969}
1970
1971
1972int ByteArray::get_int(int index) {
1973 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1974 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1975}
1976
1977
1978ByteArray* ByteArray::FromDataStartAddress(Address address) {
1979 ASSERT_TAG_ALIGNED(address);
1980 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1981}
1982
1983
1984Address ByteArray::GetDataStartAddress() {
1985 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1986}
1987
1988
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001989uint8_t* PixelArray::external_pointer() {
1990 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1991 return reinterpret_cast<uint8_t*>(ptr);
1992}
1993
1994
1995void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1996 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1997 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1998}
1999
2000
2001uint8_t PixelArray::get(int index) {
2002 ASSERT((index >= 0) && (index < this->length()));
2003 uint8_t* ptr = external_pointer();
2004 return ptr[index];
2005}
2006
2007
2008void PixelArray::set(int index, uint8_t value) {
2009 ASSERT((index >= 0) && (index < this->length()));
2010 uint8_t* ptr = external_pointer();
2011 ptr[index] = value;
2012}
2013
2014
ager@chromium.org3811b432009-10-28 14:53:37 +00002015void* ExternalArray::external_pointer() {
2016 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2017 return reinterpret_cast<void*>(ptr);
2018}
2019
2020
2021void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2022 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2023 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2024}
2025
2026
2027int8_t ExternalByteArray::get(int index) {
2028 ASSERT((index >= 0) && (index < this->length()));
2029 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2030 return ptr[index];
2031}
2032
2033
2034void ExternalByteArray::set(int index, int8_t value) {
2035 ASSERT((index >= 0) && (index < this->length()));
2036 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2037 ptr[index] = value;
2038}
2039
2040
2041uint8_t ExternalUnsignedByteArray::get(int index) {
2042 ASSERT((index >= 0) && (index < this->length()));
2043 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2044 return ptr[index];
2045}
2046
2047
2048void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2049 ASSERT((index >= 0) && (index < this->length()));
2050 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2051 ptr[index] = value;
2052}
2053
2054
2055int16_t ExternalShortArray::get(int index) {
2056 ASSERT((index >= 0) && (index < this->length()));
2057 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2058 return ptr[index];
2059}
2060
2061
2062void ExternalShortArray::set(int index, int16_t value) {
2063 ASSERT((index >= 0) && (index < this->length()));
2064 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2065 ptr[index] = value;
2066}
2067
2068
2069uint16_t ExternalUnsignedShortArray::get(int index) {
2070 ASSERT((index >= 0) && (index < this->length()));
2071 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2072 return ptr[index];
2073}
2074
2075
2076void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2077 ASSERT((index >= 0) && (index < this->length()));
2078 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2079 ptr[index] = value;
2080}
2081
2082
2083int32_t ExternalIntArray::get(int index) {
2084 ASSERT((index >= 0) && (index < this->length()));
2085 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2086 return ptr[index];
2087}
2088
2089
2090void ExternalIntArray::set(int index, int32_t value) {
2091 ASSERT((index >= 0) && (index < this->length()));
2092 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2093 ptr[index] = value;
2094}
2095
2096
2097uint32_t ExternalUnsignedIntArray::get(int index) {
2098 ASSERT((index >= 0) && (index < this->length()));
2099 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2100 return ptr[index];
2101}
2102
2103
2104void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2105 ASSERT((index >= 0) && (index < this->length()));
2106 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2107 ptr[index] = value;
2108}
2109
2110
2111float ExternalFloatArray::get(int index) {
2112 ASSERT((index >= 0) && (index < this->length()));
2113 float* ptr = static_cast<float*>(external_pointer());
2114 return ptr[index];
2115}
2116
2117
2118void ExternalFloatArray::set(int index, float value) {
2119 ASSERT((index >= 0) && (index < this->length()));
2120 float* ptr = static_cast<float*>(external_pointer());
2121 ptr[index] = value;
2122}
2123
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002124
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002125int Map::visitor_id() {
2126 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2127}
2128
2129
2130void Map::set_visitor_id(int id) {
2131 ASSERT(0 <= id && id < 256);
2132 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2133}
2134
ager@chromium.org3811b432009-10-28 14:53:37 +00002135
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002137 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2138}
2139
2140
2141int Map::inobject_properties() {
2142 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143}
2144
2145
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002146int Map::pre_allocated_property_fields() {
2147 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2148}
2149
2150
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002152 int instance_size = map->instance_size();
2153 if (instance_size != kVariableSizeSentinel) return instance_size;
2154 // We can ignore the "symbol" bit becase it is only set for symbols
2155 // and implies a string type.
2156 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002157 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002159 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002161 if (instance_type == ASCII_STRING_TYPE) {
2162 return SeqAsciiString::SizeFor(
2163 reinterpret_cast<SeqAsciiString*>(this)->length());
2164 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002165 if (instance_type == BYTE_ARRAY_TYPE) {
2166 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2167 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002168 if (instance_type == STRING_TYPE) {
2169 return SeqTwoByteString::SizeFor(
2170 reinterpret_cast<SeqTwoByteString*>(this)->length());
2171 }
2172 ASSERT(instance_type == CODE_TYPE);
2173 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002174}
2175
2176
2177void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002178 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002179 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180 ASSERT(0 <= value && value < 256);
2181 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2182}
2183
2184
ager@chromium.org7c537e22008-10-16 08:43:32 +00002185void Map::set_inobject_properties(int value) {
2186 ASSERT(0 <= value && value < 256);
2187 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2188}
2189
2190
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002191void Map::set_pre_allocated_property_fields(int value) {
2192 ASSERT(0 <= value && value < 256);
2193 WRITE_BYTE_FIELD(this,
2194 kPreAllocatedPropertyFieldsOffset,
2195 static_cast<byte>(value));
2196}
2197
2198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199InstanceType Map::instance_type() {
2200 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2201}
2202
2203
2204void Map::set_instance_type(InstanceType value) {
2205 ASSERT(0 <= value && value < 256);
2206 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2207}
2208
2209
2210int Map::unused_property_fields() {
2211 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2212}
2213
2214
2215void Map::set_unused_property_fields(int value) {
2216 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2217}
2218
2219
2220byte Map::bit_field() {
2221 return READ_BYTE_FIELD(this, kBitFieldOffset);
2222}
2223
2224
2225void Map::set_bit_field(byte value) {
2226 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2227}
2228
2229
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002230byte Map::bit_field2() {
2231 return READ_BYTE_FIELD(this, kBitField2Offset);
2232}
2233
2234
2235void Map::set_bit_field2(byte value) {
2236 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2237}
2238
2239
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002240void Map::set_non_instance_prototype(bool value) {
2241 if (value) {
2242 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2243 } else {
2244 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2245 }
2246}
2247
2248
2249bool Map::has_non_instance_prototype() {
2250 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2251}
2252
2253
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002254void Map::set_function_with_prototype(bool value) {
2255 if (value) {
2256 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2257 } else {
2258 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2259 }
2260}
2261
2262
2263bool Map::function_with_prototype() {
2264 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2265}
2266
2267
ager@chromium.org870a0b62008-11-04 11:43:05 +00002268void Map::set_is_access_check_needed(bool access_check_needed) {
2269 if (access_check_needed) {
2270 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2271 } else {
2272 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2273 }
2274}
2275
2276
2277bool Map::is_access_check_needed() {
2278 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2279}
2280
2281
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002282void Map::set_is_extensible(bool value) {
2283 if (value) {
2284 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2285 } else {
2286 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2287 }
2288}
2289
2290bool Map::is_extensible() {
2291 return ((1 << kIsExtensible) & bit_field2()) != 0;
2292}
2293
2294
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002295void Map::set_attached_to_shared_function_info(bool value) {
2296 if (value) {
2297 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2298 } else {
2299 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2300 }
2301}
2302
2303bool Map::attached_to_shared_function_info() {
2304 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2305}
2306
2307
2308void Map::set_is_shared(bool value) {
2309 if (value) {
2310 set_bit_field2(bit_field2() | (1 << kIsShared));
2311 } else {
2312 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2313 }
2314}
2315
2316bool Map::is_shared() {
2317 return ((1 << kIsShared) & bit_field2()) != 0;
2318}
2319
2320
2321JSFunction* Map::unchecked_constructor() {
2322 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2323}
2324
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002325
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326Code::Flags Code::flags() {
2327 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2328}
2329
2330
2331void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002332 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002334 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2335 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002336 ExtractArgumentsCountFromFlags(flags) >= 0);
2337 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2338}
2339
2340
2341Code::Kind Code::kind() {
2342 return ExtractKindFromFlags(flags());
2343}
2344
2345
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002346InLoopFlag Code::ic_in_loop() {
2347 return ExtractICInLoopFromFlags(flags());
2348}
2349
2350
kasper.lund7276f142008-07-30 08:49:36 +00002351InlineCacheState Code::ic_state() {
2352 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353 // Only allow uninitialized or debugger states for non-IC code
2354 // objects. This is used in the debugger to determine whether or not
2355 // a call to code object has been replaced with a debug break call.
2356 ASSERT(is_inline_cache_stub() ||
2357 result == UNINITIALIZED ||
2358 result == DEBUG_BREAK ||
2359 result == DEBUG_PREPARE_STEP_IN);
2360 return result;
2361}
2362
2363
2364PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002365 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366 return ExtractTypeFromFlags(flags());
2367}
2368
2369
2370int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002371 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372 return ExtractArgumentsCountFromFlags(flags());
2373}
2374
2375
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002376int Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002377 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002378 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002379}
2380
2381
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002382void Code::set_major_key(int major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002383 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002384 ASSERT(0 <= major && major < 256);
2385 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002386}
2387
2388
2389bool Code::is_inline_cache_stub() {
2390 Kind kind = this->kind();
2391 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2392}
2393
2394
2395Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002396 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002397 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002399 int argc,
2400 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401 // Compute the bit mask.
2402 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002403 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002404 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405 bits |= type << kFlagsTypeShift;
2406 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002407 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408 // Cast to flags and validate result before returning it.
2409 Flags result = static_cast<Flags>(bits);
2410 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002411 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002412 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002413 ASSERT(ExtractTypeFromFlags(result) == type);
2414 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2415 return result;
2416}
2417
2418
2419Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2420 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002421 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002422 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002424 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425}
2426
2427
2428Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2429 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2430 return static_cast<Kind>(bits);
2431}
2432
2433
kasper.lund7276f142008-07-30 08:49:36 +00002434InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2435 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436 return static_cast<InlineCacheState>(bits);
2437}
2438
2439
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002440InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2441 int bits = (flags & kFlagsICInLoopMask);
2442 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2443}
2444
2445
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002446PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2447 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2448 return static_cast<PropertyType>(bits);
2449}
2450
2451
2452int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2453 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2454}
2455
2456
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002457InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2458 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2459 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2460}
2461
2462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2464 int bits = flags & ~kFlagsTypeMask;
2465 return static_cast<Flags>(bits);
2466}
2467
2468
ager@chromium.org8bb60582008-12-11 12:02:20 +00002469Code* Code::GetCodeFromTargetAddress(Address address) {
2470 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2471 // GetCodeFromTargetAddress might be called when marking objects during mark
2472 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2473 // Code::cast. Code::cast does not work when the object's map is
2474 // marked.
2475 Code* result = reinterpret_cast<Code*>(code);
2476 return result;
2477}
2478
2479
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002480Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2481 return HeapObject::
2482 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2483}
2484
2485
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002486Object* Map::prototype() {
2487 return READ_FIELD(this, kPrototypeOffset);
2488}
2489
2490
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002491void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002492 ASSERT(value->IsNull() || value->IsJSObject());
2493 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002494 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002495}
2496
2497
lrn@chromium.org303ada72010-10-27 09:33:13 +00002498MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002499 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002500 Object* obj;
2501 { MaybeObject* maybe_obj = CopyDropTransitions();
2502 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2503 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002504 Map* new_map = Map::cast(obj);
2505 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002506 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002507 return new_map;
2508}
2509
2510
lrn@chromium.org303ada72010-10-27 09:33:13 +00002511MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002512 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002513 Object* obj;
2514 { MaybeObject* maybe_obj = CopyDropTransitions();
2515 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2516 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002517 Map* new_map = Map::cast(obj);
2518 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002519 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002520 return new_map;
2521}
2522
2523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002524ACCESSORS(Map, instance_descriptors, DescriptorArray,
2525 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002526ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527ACCESSORS(Map, constructor, Object, kConstructorOffset)
2528
2529ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2530ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2531
2532ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2533ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002534ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002535
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002536ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002537
2538ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2539ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2540ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2541ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2542ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002543ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002544
2545ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2546ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2547ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2548
2549ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2550ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2551ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2552ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2553ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2554ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2555
2556ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2557ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2558
2559ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2560ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2561
2562ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2563ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002564ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2565 kPropertyAccessorsOffset)
2566ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2567 kPrototypeTemplateOffset)
2568ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2569ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2570 kNamedPropertyHandlerOffset)
2571ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2572 kIndexedPropertyHandlerOffset)
2573ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2574 kInstanceTemplateOffset)
2575ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2576ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002577ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2578 kInstanceCallHandlerOffset)
2579ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2580 kAccessCheckInfoOffset)
2581ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2582
2583ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002584ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2585 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586
2587ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2588ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2589
2590ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2591
2592ACCESSORS(Script, source, Object, kSourceOffset)
2593ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002594ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002595ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2596ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002597ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002598ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2600ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002601ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002602ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002603ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002604ACCESSORS(Script, eval_from_instructions_offset, Smi,
2605 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002606
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002607#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2609ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2610ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2611ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2612
2613ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2614ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2615ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2616ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002617#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002618
2619ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002620ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002621ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002622ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2623 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002624ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002625ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2626ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002627ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002628ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2629 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630
2631BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2632 kHiddenPrototypeBit)
2633BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2634BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2635 kNeedsAccessCheckBit)
2636BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2637 kIsExpressionBit)
2638BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2639 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002640BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002641 has_only_simple_this_property_assignments,
2642 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002643BOOL_ACCESSORS(SharedFunctionInfo,
2644 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002645 try_full_codegen,
2646 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002647BOOL_ACCESSORS(SharedFunctionInfo,
2648 compiler_hints,
2649 allows_lazy_compilation,
2650 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002651
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002652
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002653#if V8_HOST_ARCH_32_BIT
2654SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2655SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002656 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002657SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002658 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002659SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2660SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002661 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002662SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2663SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002665SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002666 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002667SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002668 kThisPropertyAssignmentsCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002669#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002670
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002671#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
2672 int holder::name() { \
2673 int value = READ_INT_FIELD(this, offset); \
2674 ASSERT(kHeapObjectTag == 1); \
2675 ASSERT((value & kHeapObjectTag) == 0); \
2676 return value >> 1; \
2677 } \
2678 void holder::set_##name(int value) { \
2679 ASSERT(kHeapObjectTag == 1); \
2680 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2681 (value & 0xC0000000) == 0x000000000); \
2682 WRITE_INT_FIELD(this, \
2683 offset, \
2684 (value << 1) & ~kHeapObjectTag); \
2685 }
2686
2687#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2688 INT_ACCESSORS(holder, name, offset)
2689
2690
2691
2692PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
2693PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
2694 kFormalParameterCountOffset)
2695
2696PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
2697 kExpectedNofPropertiesOffset)
2698PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2699
2700PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
2701 kStartPositionAndTypeOffset)
2702PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
2703
2704PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
2705 kFunctionTokenPositionOffset)
2706PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
2707 kCompilerHintsOffset)
2708
2709PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
2710 kThisPropertyAssignmentsCountOffset)
2711#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002713
2714int SharedFunctionInfo::construction_count() {
2715 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2716}
2717
2718
2719void SharedFunctionInfo::set_construction_count(int value) {
2720 ASSERT(0 <= value && value < 256);
2721 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2722}
2723
2724
2725bool SharedFunctionInfo::live_objects_may_exist() {
2726 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2727}
2728
2729
2730void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2731 if (value) {
2732 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2733 } else {
2734 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2735 }
2736}
2737
2738
2739bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2740 return initial_map() != Heap::undefined_value();
2741}
2742
2743
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002744ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2745ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2746
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002747bool Script::HasValidSource() {
2748 Object* src = this->source();
2749 if (!src->IsString()) return true;
2750 String* src_str = String::cast(src);
2751 if (!StringShape(src_str).IsExternal()) return true;
2752 if (src_str->IsAsciiRepresentation()) {
2753 return ExternalAsciiString::cast(src)->resource() != NULL;
2754 } else if (src_str->IsTwoByteRepresentation()) {
2755 return ExternalTwoByteString::cast(src)->resource() != NULL;
2756 }
2757 return true;
2758}
2759
2760
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002761void SharedFunctionInfo::DontAdaptArguments() {
2762 ASSERT(code()->kind() == Code::BUILTIN);
2763 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2764}
2765
2766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002767int SharedFunctionInfo::start_position() {
2768 return start_position_and_type() >> kStartPositionShift;
2769}
2770
2771
2772void SharedFunctionInfo::set_start_position(int start_position) {
2773 set_start_position_and_type((start_position << kStartPositionShift)
2774 | (start_position_and_type() & ~kStartPositionMask));
2775}
2776
2777
2778Code* SharedFunctionInfo::code() {
2779 return Code::cast(READ_FIELD(this, kCodeOffset));
2780}
2781
2782
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002783Code* SharedFunctionInfo::unchecked_code() {
2784 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2785}
2786
2787
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002788void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002790 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791}
2792
2793
ager@chromium.orgb5737492010-07-15 09:29:43 +00002794SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2795 return reinterpret_cast<SerializedScopeInfo*>(
2796 READ_FIELD(this, kScopeInfoOffset));
2797}
2798
2799
2800void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
2801 WriteBarrierMode mode) {
2802 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
2803 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
2804}
2805
2806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002808 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809}
2810
2811
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002812bool SharedFunctionInfo::IsApiFunction() {
2813 return function_data()->IsFunctionTemplateInfo();
2814}
2815
2816
2817FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2818 ASSERT(IsApiFunction());
2819 return FunctionTemplateInfo::cast(function_data());
2820}
2821
2822
2823bool SharedFunctionInfo::HasCustomCallGenerator() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002824 return function_data()->IsSmi();
2825}
2826
2827
2828int SharedFunctionInfo::custom_call_generator_id() {
2829 ASSERT(HasCustomCallGenerator());
2830 return Smi::cast(function_data())->value();
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002831}
2832
2833
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002834int SharedFunctionInfo::code_age() {
2835 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
2836}
2837
2838
2839void SharedFunctionInfo::set_code_age(int code_age) {
2840 set_compiler_hints(compiler_hints() |
2841 ((code_age & kCodeAgeMask) << kCodeAgeShift));
2842}
2843
2844
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002845bool JSFunction::IsBuiltin() {
2846 return context()->global()->IsJSBuiltinsObject();
2847}
2848
2849
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002850Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002851 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852}
2853
2854
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002855Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002856 return reinterpret_cast<Code*>(
2857 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002858}
2859
2860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002861void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00002862 // Skip the write barrier because code is never in new space.
2863 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002864 Address entry = value->entry();
2865 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002866}
2867
2868
2869Context* JSFunction::context() {
2870 return Context::cast(READ_FIELD(this, kContextOffset));
2871}
2872
2873
2874Object* JSFunction::unchecked_context() {
2875 return READ_FIELD(this, kContextOffset);
2876}
2877
2878
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002879SharedFunctionInfo* JSFunction::unchecked_shared() {
2880 return reinterpret_cast<SharedFunctionInfo*>(
2881 READ_FIELD(this, kSharedFunctionInfoOffset));
2882}
2883
2884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885void JSFunction::set_context(Object* value) {
2886 ASSERT(value == Heap::undefined_value() || value->IsContext());
2887 WRITE_FIELD(this, kContextOffset, value);
2888 WRITE_BARRIER(this, kContextOffset);
2889}
2890
2891ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2892 kPrototypeOrInitialMapOffset)
2893
2894
2895Map* JSFunction::initial_map() {
2896 return Map::cast(prototype_or_initial_map());
2897}
2898
2899
2900void JSFunction::set_initial_map(Map* value) {
2901 set_prototype_or_initial_map(value);
2902}
2903
2904
2905bool JSFunction::has_initial_map() {
2906 return prototype_or_initial_map()->IsMap();
2907}
2908
2909
2910bool JSFunction::has_instance_prototype() {
2911 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2912}
2913
2914
2915bool JSFunction::has_prototype() {
2916 return map()->has_non_instance_prototype() || has_instance_prototype();
2917}
2918
2919
2920Object* JSFunction::instance_prototype() {
2921 ASSERT(has_instance_prototype());
2922 if (has_initial_map()) return initial_map()->prototype();
2923 // When there is no initial map and the prototype is a JSObject, the
2924 // initial map field is used for the prototype field.
2925 return prototype_or_initial_map();
2926}
2927
2928
2929Object* JSFunction::prototype() {
2930 ASSERT(has_prototype());
2931 // If the function's prototype property has been set to a non-JSObject
2932 // value, that value is stored in the constructor field of the map.
2933 if (map()->has_non_instance_prototype()) return map()->constructor();
2934 return instance_prototype();
2935}
2936
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002937bool JSFunction::should_have_prototype() {
2938 return map()->function_with_prototype();
2939}
2940
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002941
2942bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002943 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944}
2945
2946
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002947int JSFunction::NumberOfLiterals() {
2948 return literals()->length();
2949}
2950
2951
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2953 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002954 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002955}
2956
2957
2958void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2959 Object* value) {
2960 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002961 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2962 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2963}
2964
2965
2966Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2967 ASSERT(0 <= id && id < kJSBuiltinsCount);
2968 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2969}
2970
2971
2972void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2973 Code* value) {
2974 ASSERT(0 <= id && id < kJSBuiltinsCount);
2975 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2976 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977}
2978
2979
2980Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002981 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002982}
2983
2984
2985void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002986 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002987}
2988
2989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990ACCESSORS(JSValue, value, Object, kValueOffset)
2991
2992
2993JSValue* JSValue::cast(Object* obj) {
2994 ASSERT(obj->IsJSValue());
2995 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2996 return reinterpret_cast<JSValue*>(obj);
2997}
2998
2999
3000INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003001ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003002
3003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004byte* Code::instruction_start() {
3005 return FIELD_ADDR(this, kHeaderSize);
3006}
3007
3008
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003009byte* Code::instruction_end() {
3010 return instruction_start() + instruction_size();
3011}
3012
3013
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003014int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003015 return RoundUp(instruction_size(), kObjectAlignment);
3016}
3017
3018
3019ByteArray* Code::unchecked_relocation_info() {
3020 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003021}
3022
3023
3024byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003025 return unchecked_relocation_info()->GetDataStartAddress();
3026}
3027
3028
3029int Code::relocation_size() {
3030 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003031}
3032
3033
3034byte* Code::entry() {
3035 return instruction_start();
3036}
3037
3038
3039bool Code::contains(byte* pc) {
3040 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003041 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003042}
3043
3044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003045ACCESSORS(JSArray, length, Object, kLengthOffset)
3046
3047
ager@chromium.org236ad962008-09-25 09:45:57 +00003048ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003049
3050
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003051JSRegExp::Type JSRegExp::TypeTag() {
3052 Object* data = this->data();
3053 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3054 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3055 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003056}
3057
3058
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003059int JSRegExp::CaptureCount() {
3060 switch (TypeTag()) {
3061 case ATOM:
3062 return 0;
3063 case IRREGEXP:
3064 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3065 default:
3066 UNREACHABLE();
3067 return -1;
3068 }
3069}
3070
3071
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003072JSRegExp::Flags JSRegExp::GetFlags() {
3073 ASSERT(this->data()->IsFixedArray());
3074 Object* data = this->data();
3075 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3076 return Flags(smi->value());
3077}
3078
3079
3080String* JSRegExp::Pattern() {
3081 ASSERT(this->data()->IsFixedArray());
3082 Object* data = this->data();
3083 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3084 return pattern;
3085}
3086
3087
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003088Object* JSRegExp::DataAt(int index) {
3089 ASSERT(TypeTag() != NOT_COMPILED);
3090 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003091}
3092
3093
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003094void JSRegExp::SetDataAt(int index, Object* value) {
3095 ASSERT(TypeTag() != NOT_COMPILED);
3096 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3097 FixedArray::cast(data())->set(index, value);
3098}
3099
3100
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003101JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003102 if (map()->has_fast_elements()) {
3103 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3104 elements()->map() == Heap::fixed_cow_array_map());
3105 return FAST_ELEMENTS;
3106 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003107 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003108 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003109 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3110 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003111 ASSERT(array->IsDictionary());
3112 return DICTIONARY_ELEMENTS;
3113 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003114 if (array->IsExternalArray()) {
3115 switch (array->map()->instance_type()) {
3116 case EXTERNAL_BYTE_ARRAY_TYPE:
3117 return EXTERNAL_BYTE_ELEMENTS;
3118 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3119 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3120 case EXTERNAL_SHORT_ARRAY_TYPE:
3121 return EXTERNAL_SHORT_ELEMENTS;
3122 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3123 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3124 case EXTERNAL_INT_ARRAY_TYPE:
3125 return EXTERNAL_INT_ELEMENTS;
3126 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3127 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3128 default:
3129 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3130 return EXTERNAL_FLOAT_ELEMENTS;
3131 }
3132 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003133 ASSERT(array->IsPixelArray());
3134 return PIXEL_ELEMENTS;
3135}
3136
3137
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003138bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003139 return GetElementsKind() == FAST_ELEMENTS;
3140}
3141
3142
3143bool JSObject::HasDictionaryElements() {
3144 return GetElementsKind() == DICTIONARY_ELEMENTS;
3145}
3146
3147
3148bool JSObject::HasPixelElements() {
3149 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003150}
3151
3152
ager@chromium.org3811b432009-10-28 14:53:37 +00003153bool JSObject::HasExternalArrayElements() {
3154 return (HasExternalByteElements() ||
3155 HasExternalUnsignedByteElements() ||
3156 HasExternalShortElements() ||
3157 HasExternalUnsignedShortElements() ||
3158 HasExternalIntElements() ||
3159 HasExternalUnsignedIntElements() ||
3160 HasExternalFloatElements());
3161}
3162
3163
3164bool JSObject::HasExternalByteElements() {
3165 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3166}
3167
3168
3169bool JSObject::HasExternalUnsignedByteElements() {
3170 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3171}
3172
3173
3174bool JSObject::HasExternalShortElements() {
3175 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3176}
3177
3178
3179bool JSObject::HasExternalUnsignedShortElements() {
3180 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3181}
3182
3183
3184bool JSObject::HasExternalIntElements() {
3185 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3186}
3187
3188
3189bool JSObject::HasExternalUnsignedIntElements() {
3190 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3191}
3192
3193
3194bool JSObject::HasExternalFloatElements() {
3195 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3196}
3197
3198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003199bool JSObject::HasNamedInterceptor() {
3200 return map()->has_named_interceptor();
3201}
3202
3203
3204bool JSObject::HasIndexedInterceptor() {
3205 return map()->has_indexed_interceptor();
3206}
3207
3208
ager@chromium.org5c838252010-02-19 08:53:10 +00003209bool JSObject::AllowsSetElementsLength() {
3210 bool result = elements()->IsFixedArray();
3211 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3212 return result;
3213}
3214
3215
lrn@chromium.org303ada72010-10-27 09:33:13 +00003216MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003217 ASSERT(HasFastElements());
3218 FixedArray* elems = FixedArray::cast(elements());
3219 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003220 Object* writable_elems;
3221 { MaybeObject* maybe_writable_elems =
3222 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3223 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3224 return maybe_writable_elems;
3225 }
3226 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003227 set_elements(FixedArray::cast(writable_elems));
3228 Counters::cow_arrays_converted.Increment();
3229 return writable_elems;
3230}
3231
3232
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003233StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003235 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236}
3237
3238
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003239NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003240 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003241 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242}
3243
3244
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003245bool String::IsHashFieldComputed(uint32_t field) {
3246 return (field & kHashNotComputedMask) == 0;
3247}
3248
3249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003251 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252}
3253
3254
3255uint32_t String::Hash() {
3256 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003257 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003258 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003259 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003260 return ComputeAndSetHash();
3261}
3262
3263
ager@chromium.org7c537e22008-10-16 08:43:32 +00003264StringHasher::StringHasher(int length)
3265 : length_(length),
3266 raw_running_hash_(0),
3267 array_index_(0),
3268 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3269 is_first_char_(true),
3270 is_valid_(true) { }
3271
3272
3273bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003274 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003275}
3276
3277
3278void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003279 // Use the Jenkins one-at-a-time hash function to update the hash
3280 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003281 raw_running_hash_ += c;
3282 raw_running_hash_ += (raw_running_hash_ << 10);
3283 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003284 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003285 if (is_array_index_) {
3286 if (c < '0' || c > '9') {
3287 is_array_index_ = false;
3288 } else {
3289 int d = c - '0';
3290 if (is_first_char_) {
3291 is_first_char_ = false;
3292 if (c == '0' && length_ > 1) {
3293 is_array_index_ = false;
3294 return;
3295 }
3296 }
3297 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3298 is_array_index_ = false;
3299 } else {
3300 array_index_ = array_index_ * 10 + d;
3301 }
3302 }
3303 }
3304}
3305
3306
3307void StringHasher::AddCharacterNoIndex(uc32 c) {
3308 ASSERT(!is_array_index());
3309 raw_running_hash_ += c;
3310 raw_running_hash_ += (raw_running_hash_ << 10);
3311 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3312}
3313
3314
3315uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003316 // Get the calculated raw hash value and do some more bit ops to distribute
3317 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003318 uint32_t result = raw_running_hash_;
3319 result += (result << 3);
3320 result ^= (result >> 11);
3321 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003322 if (result == 0) {
3323 result = 27;
3324 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003325 return result;
3326}
3327
3328
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003330 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003331 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3332 return false;
3333 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003334 return SlowAsArrayIndex(index);
3335}
3336
3337
3338Object* JSObject::GetPrototype() {
3339 return JSObject::cast(this)->map()->prototype();
3340}
3341
3342
3343PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3344 return GetPropertyAttributeWithReceiver(this, key);
3345}
3346
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003347// TODO(504): this may be useful in other places too where JSGlobalProxy
3348// is used.
3349Object* JSObject::BypassGlobalProxy() {
3350 if (IsJSGlobalProxy()) {
3351 Object* proto = GetPrototype();
3352 if (proto->IsNull()) return Heap::undefined_value();
3353 ASSERT(proto->IsJSGlobalObject());
3354 return proto;
3355 }
3356 return this;
3357}
3358
3359
3360bool JSObject::HasHiddenPropertiesObject() {
3361 ASSERT(!IsJSGlobalProxy());
3362 return GetPropertyAttributePostInterceptor(this,
3363 Heap::hidden_symbol(),
3364 false) != ABSENT;
3365}
3366
3367
3368Object* JSObject::GetHiddenPropertiesObject() {
3369 ASSERT(!IsJSGlobalProxy());
3370 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003371 // You can't install a getter on a property indexed by the hidden symbol,
3372 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3373 // object.
3374 Object* result =
3375 GetLocalPropertyPostInterceptor(this,
3376 Heap::hidden_symbol(),
3377 &attributes)->ToObjectUnchecked();
3378 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003379}
3380
3381
lrn@chromium.org303ada72010-10-27 09:33:13 +00003382MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003383 ASSERT(!IsJSGlobalProxy());
3384 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3385 hidden_obj,
3386 DONT_ENUM);
3387}
3388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003389
3390bool JSObject::HasElement(uint32_t index) {
3391 return HasElementWithReceiver(this, index);
3392}
3393
3394
3395bool AccessorInfo::all_can_read() {
3396 return BooleanBit::get(flag(), kAllCanReadBit);
3397}
3398
3399
3400void AccessorInfo::set_all_can_read(bool value) {
3401 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3402}
3403
3404
3405bool AccessorInfo::all_can_write() {
3406 return BooleanBit::get(flag(), kAllCanWriteBit);
3407}
3408
3409
3410void AccessorInfo::set_all_can_write(bool value) {
3411 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3412}
3413
3414
ager@chromium.org870a0b62008-11-04 11:43:05 +00003415bool AccessorInfo::prohibits_overwriting() {
3416 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3417}
3418
3419
3420void AccessorInfo::set_prohibits_overwriting(bool value) {
3421 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3422}
3423
3424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003425PropertyAttributes AccessorInfo::property_attributes() {
3426 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3427}
3428
3429
3430void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3431 ASSERT(AttributesField::is_valid(attributes));
3432 int rest_value = flag()->value() & ~AttributesField::mask();
3433 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3434}
3435
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003436template<typename Shape, typename Key>
3437void Dictionary<Shape, Key>::SetEntry(int entry,
3438 Object* key,
3439 Object* value,
3440 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003441 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003442 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003443 AssertNoAllocation no_gc;
3444 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003445 FixedArray::set(index, key, mode);
3446 FixedArray::set(index+1, value, mode);
3447 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448}
3449
3450
3451void Map::ClearCodeCache() {
3452 // No write barrier is needed since empty_fixed_array is not in new space.
3453 // Please note this function is used during marking:
3454 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003455 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3456 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003457}
3458
3459
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003460void JSArray::EnsureSize(int required_size) {
3461 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003462 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003463 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3464 if (elts->length() < required_size) {
3465 // Doubling in size would be overkill, but leave some slack to avoid
3466 // constantly growing.
3467 Expand(required_size + (required_size >> 3));
3468 // It's a performance benefit to keep a frequently used array in new-space.
3469 } else if (!Heap::new_space()->Contains(elts) &&
3470 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3471 // Expand will allocate a new backing store in new space even if the size
3472 // we asked for isn't larger than what we had before.
3473 Expand(required_size);
3474 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003475}
3476
3477
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003478void JSArray::set_length(Smi* length) {
3479 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3480}
3481
3482
ager@chromium.org7c537e22008-10-16 08:43:32 +00003483void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003484 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003485 set_elements(storage);
3486}
3487
3488
lrn@chromium.org303ada72010-10-27 09:33:13 +00003489MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003490 if (length() == 0) return this;
3491 return Heap::CopyFixedArray(this);
3492}
3493
3494
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003495int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3496 return map->instance_size();
3497}
3498
3499
3500void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3501 v->VisitExternalReference(
3502 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3503}
3504
3505
3506template<typename StaticVisitor>
3507void Proxy::ProxyIterateBody() {
3508 StaticVisitor::VisitExternalReference(
3509 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3510}
3511
3512
3513void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3514 typedef v8::String::ExternalAsciiStringResource Resource;
3515 v->VisitExternalAsciiString(
3516 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3517}
3518
3519
3520template<typename StaticVisitor>
3521void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3522 typedef v8::String::ExternalAsciiStringResource Resource;
3523 StaticVisitor::VisitExternalAsciiString(
3524 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3525}
3526
3527
3528void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3529 typedef v8::String::ExternalStringResource Resource;
3530 v->VisitExternalTwoByteString(
3531 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3532}
3533
3534
3535template<typename StaticVisitor>
3536void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3537 typedef v8::String::ExternalStringResource Resource;
3538 StaticVisitor::VisitExternalTwoByteString(
3539 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3540}
3541
3542#define SLOT_ADDR(obj, offset) \
3543 reinterpret_cast<Object**>((obj)->address() + offset)
3544
3545template<int start_offset, int end_offset, int size>
3546void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3547 HeapObject* obj,
3548 ObjectVisitor* v) {
3549 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3550}
3551
3552
3553template<int start_offset>
3554void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3555 int object_size,
3556 ObjectVisitor* v) {
3557 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3558}
3559
3560#undef SLOT_ADDR
3561
3562
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003563#undef CAST_ACCESSOR
3564#undef INT_ACCESSORS
3565#undef SMI_ACCESSORS
3566#undef ACCESSORS
3567#undef FIELD_ADDR
3568#undef READ_FIELD
3569#undef WRITE_FIELD
3570#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003571#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003572#undef READ_MEMADDR_FIELD
3573#undef WRITE_MEMADDR_FIELD
3574#undef READ_DOUBLE_FIELD
3575#undef WRITE_DOUBLE_FIELD
3576#undef READ_INT_FIELD
3577#undef WRITE_INT_FIELD
3578#undef READ_SHORT_FIELD
3579#undef WRITE_SHORT_FIELD
3580#undef READ_BYTE_FIELD
3581#undef WRITE_BYTE_FIELD
3582
3583
3584} } // namespace v8::internal
3585
3586#endif // V8_OBJECTS_INL_H_