blob: abfd4436dfa1720a540d7777d555b5c5f58ccefb [file] [log] [blame]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001// Copyright 2010 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
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000462bool Object::IsDeoptimizationInputData() {
463 // Must be a fixed array.
464 if (!IsFixedArray()) return false;
465
466 // There's no sure way to detect the difference between a fixed array and
467 // a deoptimization data array. Since this is used for asserts we can
468 // check that the length is zero or else the fixed size plus a multiple of
469 // the entry size.
470 int length = FixedArray::cast(this)->length();
471 if (length == 0) return true;
472
473 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
474 return length >= 0 &&
475 length % DeoptimizationInputData::kDeoptEntrySize == 0;
476}
477
478
479bool Object::IsDeoptimizationOutputData() {
480 if (!IsFixedArray()) return false;
481 // There's actually no way to see the difference between a fixed array and
482 // a deoptimization data array. Since this is used for asserts we can check
483 // that the length is plausible though.
484 if (FixedArray::cast(this)->length() % 2 != 0) return false;
485 return true;
486}
487
488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489bool Object::IsContext() {
490 return Object::IsHeapObject()
491 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000492 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493 HeapObject::cast(this)->map() == Heap::global_context_map());
494}
495
496
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000497bool Object::IsCatchContext() {
498 return Object::IsHeapObject()
499 && HeapObject::cast(this)->map() == Heap::catch_context_map();
500}
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503bool Object::IsGlobalContext() {
504 return Object::IsHeapObject()
505 && HeapObject::cast(this)->map() == Heap::global_context_map();
506}
507
508
509bool Object::IsJSFunction() {
510 return Object::IsHeapObject()
511 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
512}
513
514
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000515template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516 return obj->IsJSFunction();
517}
518
519
520bool Object::IsCode() {
521 return Object::IsHeapObject()
522 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
523}
524
525
526bool Object::IsOddball() {
527 return Object::IsHeapObject()
528 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
529}
530
531
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000532bool Object::IsJSGlobalPropertyCell() {
533 return Object::IsHeapObject()
534 && HeapObject::cast(this)->map()->instance_type()
535 == JS_GLOBAL_PROPERTY_CELL_TYPE;
536}
537
538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000539bool Object::IsSharedFunctionInfo() {
540 return Object::IsHeapObject() &&
541 (HeapObject::cast(this)->map()->instance_type() ==
542 SHARED_FUNCTION_INFO_TYPE);
543}
544
545
546bool Object::IsJSValue() {
547 return Object::IsHeapObject()
548 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
549}
550
551
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000552bool Object::IsStringWrapper() {
553 return IsJSValue() && JSValue::cast(this)->value()->IsString();
554}
555
556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557bool Object::IsProxy() {
558 return Object::IsHeapObject()
559 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
560}
561
562
563bool Object::IsBoolean() {
564 return IsTrue() || IsFalse();
565}
566
567
568bool Object::IsJSArray() {
569 return Object::IsHeapObject()
570 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
571}
572
573
ager@chromium.org236ad962008-09-25 09:45:57 +0000574bool Object::IsJSRegExp() {
575 return Object::IsHeapObject()
576 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
577}
578
579
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000580template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000581 return obj->IsJSArray();
582}
583
584
585bool Object::IsHashTable() {
586 return Object::IsHeapObject()
587 && HeapObject::cast(this)->map() == Heap::hash_table_map();
588}
589
590
591bool Object::IsDictionary() {
592 return IsHashTable() && this != Heap::symbol_table();
593}
594
595
596bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000597 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000598}
599
600
ager@chromium.orgac091b72010-05-05 07:34:42 +0000601bool Object::IsJSFunctionResultCache() {
602 if (!IsFixedArray()) return false;
603 FixedArray* self = FixedArray::cast(this);
604 int length = self->length();
605 if (length < JSFunctionResultCache::kEntriesIndex) return false;
606 if ((length - JSFunctionResultCache::kEntriesIndex)
607 % JSFunctionResultCache::kEntrySize != 0) {
608 return false;
609 }
610#ifdef DEBUG
611 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
612#endif
613 return true;
614}
615
616
ricow@chromium.org65fae842010-08-25 15:26:24 +0000617bool Object::IsNormalizedMapCache() {
618 if (!IsFixedArray()) return false;
619 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
620 return false;
621 }
622#ifdef DEBUG
623 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
624#endif
625 return true;
626}
627
628
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000629bool Object::IsCompilationCacheTable() {
630 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000631}
632
633
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000634bool Object::IsCodeCacheHashTable() {
635 return IsHashTable();
636}
637
638
ager@chromium.org236ad962008-09-25 09:45:57 +0000639bool Object::IsMapCache() {
640 return IsHashTable();
641}
642
643
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644bool Object::IsPrimitive() {
645 return IsOddball() || IsNumber() || IsString();
646}
647
648
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000649bool Object::IsJSGlobalProxy() {
650 bool result = IsHeapObject() &&
651 (HeapObject::cast(this)->map()->instance_type() ==
652 JS_GLOBAL_PROXY_TYPE);
653 ASSERT(!result || IsAccessCheckNeeded());
654 return result;
655}
656
657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000658bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000659 if (!IsHeapObject()) return false;
660
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000661 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000662 return type == JS_GLOBAL_OBJECT_TYPE ||
663 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000664}
665
666
667bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668 return IsHeapObject() &&
669 (HeapObject::cast(this)->map()->instance_type() ==
670 JS_GLOBAL_OBJECT_TYPE);
671}
672
673
674bool Object::IsJSBuiltinsObject() {
675 return IsHeapObject() &&
676 (HeapObject::cast(this)->map()->instance_type() ==
677 JS_BUILTINS_OBJECT_TYPE);
678}
679
680
681bool Object::IsUndetectableObject() {
682 return IsHeapObject()
683 && HeapObject::cast(this)->map()->is_undetectable();
684}
685
686
687bool Object::IsAccessCheckNeeded() {
688 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690}
691
692
693bool Object::IsStruct() {
694 if (!IsHeapObject()) return false;
695 switch (HeapObject::cast(this)->map()->instance_type()) {
696#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
697 STRUCT_LIST(MAKE_STRUCT_CASE)
698#undef MAKE_STRUCT_CASE
699 default: return false;
700 }
701}
702
703
704#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
705 bool Object::Is##Name() { \
706 return Object::IsHeapObject() \
707 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
708 }
709 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
710#undef MAKE_STRUCT_PREDICATE
711
712
713bool Object::IsUndefined() {
714 return this == Heap::undefined_value();
715}
716
717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000718bool Object::IsNull() {
719 return this == Heap::null_value();
720}
721
722
723bool Object::IsTrue() {
724 return this == Heap::true_value();
725}
726
727
728bool Object::IsFalse() {
729 return this == Heap::false_value();
730}
731
732
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000733bool Object::IsArgumentsMarker() {
734 return this == Heap::arguments_marker();
735}
736
737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738double Object::Number() {
739 ASSERT(IsNumber());
740 return IsSmi()
741 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
742 : reinterpret_cast<HeapNumber*>(this)->value();
743}
744
745
746
lrn@chromium.org303ada72010-10-27 09:33:13 +0000747MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748 if (IsSmi()) return this;
749 if (IsHeapNumber()) {
750 double value = HeapNumber::cast(this)->value();
751 int int_value = FastD2I(value);
752 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
753 return Smi::FromInt(int_value);
754 }
755 }
756 return Failure::Exception();
757}
758
759
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000760bool Object::HasSpecificClassOf(String* name) {
761 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
762}
763
764
lrn@chromium.org303ada72010-10-27 09:33:13 +0000765MaybeObject* Object::GetElement(uint32_t index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000766 return GetElementWithReceiver(this, index);
767}
768
769
lrn@chromium.org303ada72010-10-27 09:33:13 +0000770Object* Object::GetElementNoExceptionThrown(uint32_t index) {
771 MaybeObject* maybe = GetElementWithReceiver(this, index);
772 ASSERT(!maybe->IsFailure());
773 Object* result = NULL; // Initialization to please compiler.
774 maybe->ToObject(&result);
775 return result;
776}
777
778
779MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000780 PropertyAttributes attributes;
781 return GetPropertyWithReceiver(this, key, &attributes);
782}
783
784
lrn@chromium.org303ada72010-10-27 09:33:13 +0000785MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786 return GetPropertyWithReceiver(this, key, attributes);
787}
788
789
790#define FIELD_ADDR(p, offset) \
791 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
792
793#define READ_FIELD(p, offset) \
794 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
795
796#define WRITE_FIELD(p, offset, value) \
797 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
798
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800#define WRITE_BARRIER(object, offset) \
801 Heap::RecordWrite(object->address(), offset);
802
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000803// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000804// write due to the assert validating the written value.
805#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
806 if (mode == UPDATE_WRITE_BARRIER) { \
807 Heap::RecordWrite(object->address(), offset); \
808 } else { \
809 ASSERT(mode == SKIP_WRITE_BARRIER); \
810 ASSERT(Heap::InNewSpace(object) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000811 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000812 Page::FromAddress(object->address())-> \
813 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000814 }
815
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816#define READ_DOUBLE_FIELD(p, offset) \
817 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
818
819#define WRITE_DOUBLE_FIELD(p, offset, value) \
820 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
821
822#define READ_INT_FIELD(p, offset) \
823 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
824
825#define WRITE_INT_FIELD(p, offset, value) \
826 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
827
ager@chromium.org3e875802009-06-29 08:26:34 +0000828#define READ_INTPTR_FIELD(p, offset) \
829 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
830
831#define WRITE_INTPTR_FIELD(p, offset, value) \
832 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
833
ager@chromium.org7c537e22008-10-16 08:43:32 +0000834#define READ_UINT32_FIELD(p, offset) \
835 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
836
837#define WRITE_UINT32_FIELD(p, offset, value) \
838 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
839
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840#define READ_SHORT_FIELD(p, offset) \
841 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
842
843#define WRITE_SHORT_FIELD(p, offset, value) \
844 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
845
846#define READ_BYTE_FIELD(p, offset) \
847 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
848
849#define WRITE_BYTE_FIELD(p, offset, value) \
850 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
851
852
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000853Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
854 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855}
856
857
858int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000859 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860}
861
862
863Smi* Smi::FromInt(int value) {
864 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000865 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000866 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000867 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000868 return reinterpret_cast<Smi*>(tagged_value);
869}
870
871
872Smi* Smi::FromIntptr(intptr_t value) {
873 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
875 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000876}
877
878
879Failure::Type Failure::type() const {
880 return static_cast<Type>(value() & kFailureTypeTagMask);
881}
882
883
884bool Failure::IsInternalError() const {
885 return type() == INTERNAL_ERROR;
886}
887
888
889bool Failure::IsOutOfMemoryException() const {
890 return type() == OUT_OF_MEMORY_EXCEPTION;
891}
892
893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000894AllocationSpace Failure::allocation_space() const {
895 ASSERT_EQ(RETRY_AFTER_GC, type());
896 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
897 & kSpaceTagMask);
898}
899
900
901Failure* Failure::InternalError() {
902 return Construct(INTERNAL_ERROR);
903}
904
905
906Failure* Failure::Exception() {
907 return Construct(EXCEPTION);
908}
909
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000910
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000911Failure* Failure::OutOfMemoryException() {
912 return Construct(OUT_OF_MEMORY_EXCEPTION);
913}
914
915
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000916intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000917 return static_cast<intptr_t>(
918 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000919}
920
921
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000922Failure* Failure::RetryAfterGC() {
923 return RetryAfterGC(NEW_SPACE);
924}
925
926
927Failure* Failure::RetryAfterGC(AllocationSpace space) {
928 ASSERT((space & ~kSpaceTagMask) == 0);
929 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000930}
931
932
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000933Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000934 uintptr_t info =
935 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000936 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000937 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000938}
939
940
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000941bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942#ifdef DEBUG
943 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
944#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000945
946#ifdef V8_TARGET_ARCH_X64
947 // To be representable as a long smi, the value must be a 32-bit integer.
948 bool result = (value == static_cast<int32_t>(value));
949#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950 // To be representable as an tagged small integer, the two
951 // most-significant bits of 'value' must be either 00 or 11 due to
952 // sign-extension. To check this we add 01 to the two
953 // most-significant bits, and check if the most-significant bit is 0
954 //
955 // CAUTION: The original code below:
956 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
957 // may lead to incorrect results according to the C language spec, and
958 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
959 // compiler may produce undefined results in case of signed integer
960 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000961 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000962#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000963 ASSERT(result == in_range);
964 return result;
965}
966
967
kasper.lund7276f142008-07-30 08:49:36 +0000968MapWord MapWord::FromMap(Map* map) {
969 return MapWord(reinterpret_cast<uintptr_t>(map));
970}
971
972
973Map* MapWord::ToMap() {
974 return reinterpret_cast<Map*>(value_);
975}
976
977
978bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000979 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000980}
981
982
983MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000984 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
985 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000986}
987
988
989HeapObject* MapWord::ToForwardingAddress() {
990 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000991 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000992}
993
994
995bool MapWord::IsMarked() {
996 return (value_ & kMarkingMask) == 0;
997}
998
999
1000void MapWord::SetMark() {
1001 value_ &= ~kMarkingMask;
1002}
1003
1004
1005void MapWord::ClearMark() {
1006 value_ |= kMarkingMask;
1007}
1008
1009
1010bool MapWord::IsOverflowed() {
1011 return (value_ & kOverflowMask) != 0;
1012}
1013
1014
1015void MapWord::SetOverflow() {
1016 value_ |= kOverflowMask;
1017}
1018
1019
1020void MapWord::ClearOverflow() {
1021 value_ &= ~kOverflowMask;
1022}
1023
1024
1025MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1026 // Offset is the distance in live bytes from the first live object in the
1027 // same page. The offset between two objects in the same page should not
1028 // exceed the object area size of a page.
1029 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1030
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001031 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001032 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1033
1034 Page* map_page = Page::FromAddress(map_address);
1035 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1036
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001037 uintptr_t map_page_offset =
1038 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001039
1040 uintptr_t encoding =
1041 (compact_offset << kForwardingOffsetShift) |
1042 (map_page_offset << kMapPageOffsetShift) |
1043 (map_page->mc_page_index << kMapPageIndexShift);
1044 return MapWord(encoding);
1045}
1046
1047
1048Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001049 int map_page_index =
1050 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001051 ASSERT_MAP_PAGE_INDEX(map_page_index);
1052
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001053 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001054 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1055 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001056
1057 return (map_space->PageAddress(map_page_index) + map_page_offset);
1058}
1059
1060
1061int MapWord::DecodeOffset() {
1062 // The offset field is represented in the kForwardingOffsetBits
1063 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001064 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1065 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1066 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001067}
1068
1069
1070MapWord MapWord::FromEncodedAddress(Address address) {
1071 return MapWord(reinterpret_cast<uintptr_t>(address));
1072}
1073
1074
1075Address MapWord::ToEncodedAddress() {
1076 return reinterpret_cast<Address>(value_);
1077}
1078
1079
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001080#ifdef DEBUG
1081void HeapObject::VerifyObjectField(int offset) {
1082 VerifyPointer(READ_FIELD(this, offset));
1083}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001084
1085void HeapObject::VerifySmiField(int offset) {
1086 ASSERT(READ_FIELD(this, offset)->IsSmi());
1087}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001088#endif
1089
1090
1091Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001092 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001093}
1094
1095
1096void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001097 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098}
1099
1100
kasper.lund7276f142008-07-30 08:49:36 +00001101MapWord HeapObject::map_word() {
1102 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1103}
1104
1105
1106void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001107 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001108 // here.
1109 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1110}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001111
1112
1113HeapObject* HeapObject::FromAddress(Address address) {
1114 ASSERT_TAG_ALIGNED(address);
1115 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1116}
1117
1118
1119Address HeapObject::address() {
1120 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1121}
1122
1123
1124int HeapObject::Size() {
1125 return SizeFromMap(map());
1126}
1127
1128
1129void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1130 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1131 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1132}
1133
1134
1135void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1136 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1137}
1138
1139
kasper.lund7276f142008-07-30 08:49:36 +00001140bool HeapObject::IsMarked() {
1141 return map_word().IsMarked();
1142}
1143
1144
1145void HeapObject::SetMark() {
1146 ASSERT(!IsMarked());
1147 MapWord first_word = map_word();
1148 first_word.SetMark();
1149 set_map_word(first_word);
1150}
1151
1152
1153void HeapObject::ClearMark() {
1154 ASSERT(IsMarked());
1155 MapWord first_word = map_word();
1156 first_word.ClearMark();
1157 set_map_word(first_word);
1158}
1159
1160
1161bool HeapObject::IsOverflowed() {
1162 return map_word().IsOverflowed();
1163}
1164
1165
1166void HeapObject::SetOverflow() {
1167 MapWord first_word = map_word();
1168 first_word.SetOverflow();
1169 set_map_word(first_word);
1170}
1171
1172
1173void HeapObject::ClearOverflow() {
1174 ASSERT(IsOverflowed());
1175 MapWord first_word = map_word();
1176 first_word.ClearOverflow();
1177 set_map_word(first_word);
1178}
1179
1180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181double HeapNumber::value() {
1182 return READ_DOUBLE_FIELD(this, kValueOffset);
1183}
1184
1185
1186void HeapNumber::set_value(double value) {
1187 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1188}
1189
1190
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001191int HeapNumber::get_exponent() {
1192 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1193 kExponentShift) - kExponentBias;
1194}
1195
1196
1197int HeapNumber::get_sign() {
1198 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1199}
1200
1201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001203
1204
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001205HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001206 Object* array = READ_FIELD(this, kElementsOffset);
1207 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001208 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1209 array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001210 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001211}
1212
1213
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001214void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001215 ASSERT(map()->has_fast_elements() ==
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001216 (value->map() == Heap::fixed_array_map() ||
1217 value->map() == Heap::fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001218 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001219 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1220 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001221 WRITE_FIELD(this, kElementsOffset, value);
1222 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1223}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224
1225
1226void JSObject::initialize_properties() {
1227 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1228 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1229}
1230
1231
1232void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001233 ASSERT(map()->has_fast_elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1235 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1236}
1237
1238
lrn@chromium.org303ada72010-10-27 09:33:13 +00001239MaybeObject* JSObject::ResetElements() {
1240 Object* obj;
1241 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1242 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1243 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001244 set_map(Map::cast(obj));
1245 initialize_elements();
1246 return this;
1247}
1248
1249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001250ACCESSORS(Oddball, to_string, String, kToStringOffset)
1251ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1252
1253
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001254Object* JSGlobalPropertyCell::value() {
1255 return READ_FIELD(this, kValueOffset);
1256}
1257
1258
1259void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1260 // The write barrier is not used for global property cells.
1261 ASSERT(!val->IsJSGlobalPropertyCell());
1262 WRITE_FIELD(this, kValueOffset, val);
1263}
1264
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001265
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001266int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001267 InstanceType type = map()->instance_type();
1268 // Check for the most common kind of JavaScript object before
1269 // falling into the generic switch. This speeds up the internal
1270 // field operations considerably on average.
1271 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1272 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001273 case JS_GLOBAL_PROXY_TYPE:
1274 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275 case JS_GLOBAL_OBJECT_TYPE:
1276 return JSGlobalObject::kSize;
1277 case JS_BUILTINS_OBJECT_TYPE:
1278 return JSBuiltinsObject::kSize;
1279 case JS_FUNCTION_TYPE:
1280 return JSFunction::kSize;
1281 case JS_VALUE_TYPE:
1282 return JSValue::kSize;
1283 case JS_ARRAY_TYPE:
1284 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001285 case JS_REGEXP_TYPE:
1286 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001287 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001288 return JSObject::kHeaderSize;
1289 default:
1290 UNREACHABLE();
1291 return 0;
1292 }
1293}
1294
1295
1296int JSObject::GetInternalFieldCount() {
1297 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001298 // Make sure to adjust for the number of in-object properties. These
1299 // properties do contribute to the size, but are not internal fields.
1300 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1301 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001302}
1303
1304
1305Object* JSObject::GetInternalField(int index) {
1306 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001307 // Internal objects do follow immediately after the header, whereas in-object
1308 // properties are at the end of the object. Therefore there is no need
1309 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001310 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1311}
1312
1313
1314void JSObject::SetInternalField(int index, Object* value) {
1315 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001316 // Internal objects do follow immediately after the header, whereas in-object
1317 // properties are at the end of the object. Therefore there is no need
1318 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319 int offset = GetHeaderSize() + (kPointerSize * index);
1320 WRITE_FIELD(this, offset, value);
1321 WRITE_BARRIER(this, offset);
1322}
1323
1324
ager@chromium.org7c537e22008-10-16 08:43:32 +00001325// Access fast-case object properties at index. The use of these routines
1326// is needed to correctly distinguish between properties stored in-object and
1327// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001328Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001329 // Adjust for the number of properties stored in the object.
1330 index -= map()->inobject_properties();
1331 if (index < 0) {
1332 int offset = map()->instance_size() + (index * kPointerSize);
1333 return READ_FIELD(this, offset);
1334 } else {
1335 ASSERT(index < properties()->length());
1336 return properties()->get(index);
1337 }
1338}
1339
1340
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001341Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001342 // Adjust for the number of properties stored in the object.
1343 index -= map()->inobject_properties();
1344 if (index < 0) {
1345 int offset = map()->instance_size() + (index * kPointerSize);
1346 WRITE_FIELD(this, offset, value);
1347 WRITE_BARRIER(this, offset);
1348 } else {
1349 ASSERT(index < properties()->length());
1350 properties()->set(index, value);
1351 }
1352 return value;
1353}
1354
1355
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001356Object* JSObject::InObjectPropertyAt(int index) {
1357 // Adjust for the number of properties stored in the object.
1358 index -= map()->inobject_properties();
1359 ASSERT(index < 0);
1360 int offset = map()->instance_size() + (index * kPointerSize);
1361 return READ_FIELD(this, offset);
1362}
1363
1364
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001365Object* JSObject::InObjectPropertyAtPut(int index,
1366 Object* value,
1367 WriteBarrierMode mode) {
1368 // Adjust for the number of properties stored in the object.
1369 index -= map()->inobject_properties();
1370 ASSERT(index < 0);
1371 int offset = map()->instance_size() + (index * kPointerSize);
1372 WRITE_FIELD(this, offset, value);
1373 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1374 return value;
1375}
1376
1377
1378
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001379void JSObject::InitializeBody(int object_size, Object* value) {
1380 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001382 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383 }
1384}
1385
1386
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001387bool JSObject::HasFastProperties() {
1388 return !properties()->IsDictionary();
1389}
1390
1391
1392int JSObject::MaxFastProperties() {
1393 // Allow extra fast properties if the object has more than
1394 // kMaxFastProperties in-object properties. When this is the case,
1395 // it is very unlikely that the object is being used as a dictionary
1396 // and there is a good chance that allowing more map transitions
1397 // will be worth it.
1398 return Max(map()->inobject_properties(), kMaxFastProperties);
1399}
1400
1401
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001402void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001403 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001404 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001405 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001406 }
1407}
1408
1409
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001410bool Object::ToArrayIndex(uint32_t* index) {
1411 if (IsSmi()) {
1412 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413 if (value < 0) return false;
1414 *index = value;
1415 return true;
1416 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001417 if (IsHeapNumber()) {
1418 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 uint32_t uint_value = static_cast<uint32_t>(value);
1420 if (value == static_cast<double>(uint_value)) {
1421 *index = uint_value;
1422 return true;
1423 }
1424 }
1425 return false;
1426}
1427
1428
1429bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1430 if (!this->IsJSValue()) return false;
1431
1432 JSValue* js_value = JSValue::cast(this);
1433 if (!js_value->value()->IsString()) return false;
1434
1435 String* str = String::cast(js_value->value());
1436 if (index >= (uint32_t)str->length()) return false;
1437
1438 return true;
1439}
1440
1441
1442Object* FixedArray::get(int index) {
1443 ASSERT(index >= 0 && index < this->length());
1444 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1445}
1446
1447
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001448void FixedArray::set(int index, Smi* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001449 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001450 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1451 int offset = kHeaderSize + index * kPointerSize;
1452 WRITE_FIELD(this, offset, value);
1453}
1454
1455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456void FixedArray::set(int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001457 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458 ASSERT(index >= 0 && index < this->length());
1459 int offset = kHeaderSize + index * kPointerSize;
1460 WRITE_FIELD(this, offset, value);
1461 WRITE_BARRIER(this, offset);
1462}
1463
1464
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001465WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001466 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1467 return UPDATE_WRITE_BARRIER;
1468}
1469
1470
1471void FixedArray::set(int index,
1472 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001473 WriteBarrierMode mode) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001474 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475 ASSERT(index >= 0 && index < this->length());
1476 int offset = kHeaderSize + index * kPointerSize;
1477 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001478 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001479}
1480
1481
1482void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001483 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001485 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001486 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1487}
1488
1489
1490void FixedArray::set_undefined(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001491 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001492 ASSERT(index >= 0 && index < this->length());
1493 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1494 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1495 Heap::undefined_value());
1496}
1497
1498
ager@chromium.org236ad962008-09-25 09:45:57 +00001499void FixedArray::set_null(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001500 ASSERT(map() != Heap::fixed_cow_array_map());
ager@chromium.org236ad962008-09-25 09:45:57 +00001501 ASSERT(index >= 0 && index < this->length());
1502 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1503 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1504}
1505
1506
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507void FixedArray::set_the_hole(int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001508 ASSERT(map() != Heap::fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001509 ASSERT(index >= 0 && index < this->length());
1510 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1511 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1512}
1513
1514
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001515void FixedArray::set_unchecked(int index, Smi* value) {
1516 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1517 int offset = kHeaderSize + index * kPointerSize;
1518 WRITE_FIELD(this, offset, value);
1519}
1520
1521
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001522void FixedArray::set_unchecked(int index,
1523 Object* value,
1524 WriteBarrierMode mode) {
1525 int offset = kHeaderSize + index * kPointerSize;
1526 WRITE_FIELD(this, offset, value);
1527 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1528}
1529
1530
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001531void FixedArray::set_null_unchecked(int index) {
1532 ASSERT(index >= 0 && index < this->length());
1533 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1534 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1535}
1536
1537
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001538Object** FixedArray::data_start() {
1539 return HeapObject::RawField(this, kHeaderSize);
1540}
1541
1542
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001543bool DescriptorArray::IsEmpty() {
1544 ASSERT(this == Heap::empty_descriptor_array() ||
1545 this->length() > 2);
1546 return this == Heap::empty_descriptor_array();
1547}
1548
1549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1551 Object* tmp = array->get(first);
1552 fast_set(array, first, array->get(second));
1553 fast_set(array, second, tmp);
1554}
1555
1556
1557int DescriptorArray::Search(String* name) {
1558 SLOW_ASSERT(IsSortedNoDuplicates());
1559
1560 // Check for empty descriptor array.
1561 int nof = number_of_descriptors();
1562 if (nof == 0) return kNotFound;
1563
1564 // Fast case: do linear search for small arrays.
1565 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001566 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001567 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001568 }
1569
1570 // Slow case: perform binary search.
1571 return BinarySearch(name, 0, nof - 1);
1572}
1573
1574
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001575int DescriptorArray::SearchWithCache(String* name) {
1576 int number = DescriptorLookupCache::Lookup(this, name);
1577 if (number == DescriptorLookupCache::kAbsent) {
1578 number = Search(name);
1579 DescriptorLookupCache::Update(this, name, number);
1580 }
1581 return number;
1582}
1583
1584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585String* DescriptorArray::GetKey(int descriptor_number) {
1586 ASSERT(descriptor_number < number_of_descriptors());
1587 return String::cast(get(ToKeyIndex(descriptor_number)));
1588}
1589
1590
1591Object* DescriptorArray::GetValue(int descriptor_number) {
1592 ASSERT(descriptor_number < number_of_descriptors());
1593 return GetContentArray()->get(ToValueIndex(descriptor_number));
1594}
1595
1596
1597Smi* DescriptorArray::GetDetails(int descriptor_number) {
1598 ASSERT(descriptor_number < number_of_descriptors());
1599 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1600}
1601
1602
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001603PropertyType DescriptorArray::GetType(int descriptor_number) {
1604 ASSERT(descriptor_number < number_of_descriptors());
1605 return PropertyDetails(GetDetails(descriptor_number)).type();
1606}
1607
1608
1609int DescriptorArray::GetFieldIndex(int descriptor_number) {
1610 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1611}
1612
1613
1614JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1615 return JSFunction::cast(GetValue(descriptor_number));
1616}
1617
1618
1619Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1620 ASSERT(GetType(descriptor_number) == CALLBACKS);
1621 return GetValue(descriptor_number);
1622}
1623
1624
1625AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1626 ASSERT(GetType(descriptor_number) == CALLBACKS);
1627 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1628 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1629}
1630
1631
1632bool DescriptorArray::IsProperty(int descriptor_number) {
1633 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1634}
1635
1636
1637bool DescriptorArray::IsTransition(int descriptor_number) {
1638 PropertyType t = GetType(descriptor_number);
1639 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1640}
1641
1642
1643bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1644 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1645}
1646
1647
1648bool DescriptorArray::IsDontEnum(int descriptor_number) {
1649 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1650}
1651
1652
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1654 desc->Init(GetKey(descriptor_number),
1655 GetValue(descriptor_number),
1656 GetDetails(descriptor_number));
1657}
1658
1659
1660void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1661 // Range check.
1662 ASSERT(descriptor_number < number_of_descriptors());
1663
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001664 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001665 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1666 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1667
1668 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1669 FixedArray* content_array = GetContentArray();
1670 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1671 fast_set(content_array, ToDetailsIndex(descriptor_number),
1672 desc->GetDetails().AsSmi());
1673}
1674
1675
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001676void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1677 Descriptor desc;
1678 src->Get(src_index, &desc);
1679 Set(index, &desc);
1680}
1681
1682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001683void DescriptorArray::Swap(int first, int second) {
1684 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1685 FixedArray* content_array = GetContentArray();
1686 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1687 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1688}
1689
1690
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001691bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001692 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001693 if (!max_index_object->IsSmi()) return false;
1694 return 0 !=
1695 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1696}
1697
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001698uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001700 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 if (!max_index_object->IsSmi()) return 0;
1702 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1703 return value >> kRequiresSlowElementsTagSize;
1704}
1705
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001706void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001707 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001708}
1709
1710
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001711// ------------------------------------
1712// Cast operations
1713
1714
1715CAST_ACCESSOR(FixedArray)
1716CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717CAST_ACCESSOR(DeoptimizationInputData)
1718CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001719CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001720CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001721CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001722CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001723CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001724CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725CAST_ACCESSOR(String)
1726CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001727CAST_ACCESSOR(SeqAsciiString)
1728CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001729CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730CAST_ACCESSOR(ExternalString)
1731CAST_ACCESSOR(ExternalAsciiString)
1732CAST_ACCESSOR(ExternalTwoByteString)
1733CAST_ACCESSOR(JSObject)
1734CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001735CAST_ACCESSOR(HeapObject)
1736CAST_ACCESSOR(HeapNumber)
1737CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001738CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739CAST_ACCESSOR(SharedFunctionInfo)
1740CAST_ACCESSOR(Map)
1741CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001742CAST_ACCESSOR(GlobalObject)
1743CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001744CAST_ACCESSOR(JSGlobalObject)
1745CAST_ACCESSOR(JSBuiltinsObject)
1746CAST_ACCESSOR(Code)
1747CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001748CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749CAST_ACCESSOR(Proxy)
1750CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001751CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001752CAST_ACCESSOR(ExternalArray)
1753CAST_ACCESSOR(ExternalByteArray)
1754CAST_ACCESSOR(ExternalUnsignedByteArray)
1755CAST_ACCESSOR(ExternalShortArray)
1756CAST_ACCESSOR(ExternalUnsignedShortArray)
1757CAST_ACCESSOR(ExternalIntArray)
1758CAST_ACCESSOR(ExternalUnsignedIntArray)
1759CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760CAST_ACCESSOR(Struct)
1761
1762
1763#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1764 STRUCT_LIST(MAKE_STRUCT_CAST)
1765#undef MAKE_STRUCT_CAST
1766
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001767
1768template <typename Shape, typename Key>
1769HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001770 ASSERT(obj->IsHashTable());
1771 return reinterpret_cast<HashTable*>(obj);
1772}
1773
1774
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001775SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1776SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1777
1778INT_ACCESSORS(PixelArray, length, kLengthOffset)
1779INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780
1781
ager@chromium.orgac091b72010-05-05 07:34:42 +00001782SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001783
1784
1785uint32_t String::hash_field() {
1786 return READ_UINT32_FIELD(this, kHashFieldOffset);
1787}
1788
1789
1790void String::set_hash_field(uint32_t value) {
1791 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001792#if V8_HOST_ARCH_64_BIT
1793 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1794#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001795}
1796
1797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798bool String::Equals(String* other) {
1799 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001800 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1801 return false;
1802 }
1803 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804}
1805
1806
lrn@chromium.org303ada72010-10-27 09:33:13 +00001807MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001808 if (!StringShape(this).IsCons()) return this;
1809 ConsString* cons = ConsString::cast(this);
1810 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001811 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812}
1813
1814
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001815String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001816 MaybeObject* flat = TryFlatten(pretenure);
1817 Object* successfully_flattened;
1818 if (flat->ToObject(&successfully_flattened)) {
1819 return String::cast(successfully_flattened);
1820 }
1821 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001822}
1823
1824
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001825uint16_t String::Get(int index) {
1826 ASSERT(index >= 0 && index < length());
1827 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001828 case kSeqStringTag | kAsciiStringTag:
1829 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1830 case kSeqStringTag | kTwoByteStringTag:
1831 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1832 case kConsStringTag | kAsciiStringTag:
1833 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001834 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001835 case kExternalStringTag | kAsciiStringTag:
1836 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1837 case kExternalStringTag | kTwoByteStringTag:
1838 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839 default:
1840 break;
1841 }
1842
1843 UNREACHABLE();
1844 return 0;
1845}
1846
1847
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001848void String::Set(int index, uint16_t value) {
1849 ASSERT(index >= 0 && index < length());
1850 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851
ager@chromium.org5ec48922009-05-05 07:25:34 +00001852 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001853 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1854 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855}
1856
1857
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001858bool String::IsFlat() {
1859 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001860 case kConsStringTag: {
1861 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001862 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001863 return second->length() == 0;
1864 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001865 default:
1866 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001867 }
1868}
1869
1870
ager@chromium.org7c537e22008-10-16 08:43:32 +00001871uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001872 ASSERT(index >= 0 && index < length());
1873 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1874}
1875
1876
ager@chromium.org7c537e22008-10-16 08:43:32 +00001877void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001878 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1879 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1880 static_cast<byte>(value));
1881}
1882
1883
ager@chromium.org7c537e22008-10-16 08:43:32 +00001884Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885 return FIELD_ADDR(this, kHeaderSize);
1886}
1887
1888
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001889char* SeqAsciiString::GetChars() {
1890 return reinterpret_cast<char*>(GetCharsAddress());
1891}
1892
1893
ager@chromium.org7c537e22008-10-16 08:43:32 +00001894Address SeqTwoByteString::GetCharsAddress() {
1895 return FIELD_ADDR(this, kHeaderSize);
1896}
1897
1898
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001899uc16* SeqTwoByteString::GetChars() {
1900 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1901}
1902
1903
ager@chromium.org7c537e22008-10-16 08:43:32 +00001904uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905 ASSERT(index >= 0 && index < length());
1906 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1907}
1908
1909
ager@chromium.org7c537e22008-10-16 08:43:32 +00001910void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911 ASSERT(index >= 0 && index < length());
1912 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1913}
1914
1915
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001916int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001917 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001918}
1919
1920
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001921int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00001922 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001923}
1924
1925
ager@chromium.org870a0b62008-11-04 11:43:05 +00001926String* ConsString::first() {
1927 return String::cast(READ_FIELD(this, kFirstOffset));
1928}
1929
1930
1931Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932 return READ_FIELD(this, kFirstOffset);
1933}
1934
1935
ager@chromium.org870a0b62008-11-04 11:43:05 +00001936void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001937 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001938 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939}
1940
1941
ager@chromium.org870a0b62008-11-04 11:43:05 +00001942String* ConsString::second() {
1943 return String::cast(READ_FIELD(this, kSecondOffset));
1944}
1945
1946
1947Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948 return READ_FIELD(this, kSecondOffset);
1949}
1950
1951
ager@chromium.org870a0b62008-11-04 11:43:05 +00001952void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001953 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001954 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955}
1956
1957
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001958ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1959 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1960}
1961
1962
1963void ExternalAsciiString::set_resource(
1964 ExternalAsciiString::Resource* resource) {
1965 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1966}
1967
1968
1969ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1970 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1971}
1972
1973
1974void ExternalTwoByteString::set_resource(
1975 ExternalTwoByteString::Resource* resource) {
1976 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1977}
1978
1979
ager@chromium.orgac091b72010-05-05 07:34:42 +00001980void JSFunctionResultCache::MakeZeroSize() {
1981 set(kFingerIndex, Smi::FromInt(kEntriesIndex));
1982 set(kCacheSizeIndex, Smi::FromInt(kEntriesIndex));
1983}
1984
1985
1986void JSFunctionResultCache::Clear() {
1987 int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
1988 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001989 MemsetPointer(entries_start,
1990 Heap::the_hole_value(),
1991 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001992 MakeZeroSize();
1993}
1994
1995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001996byte ByteArray::get(int index) {
1997 ASSERT(index >= 0 && index < this->length());
1998 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1999}
2000
2001
2002void ByteArray::set(int index, byte value) {
2003 ASSERT(index >= 0 && index < this->length());
2004 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2005}
2006
2007
2008int ByteArray::get_int(int index) {
2009 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2010 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2011}
2012
2013
2014ByteArray* ByteArray::FromDataStartAddress(Address address) {
2015 ASSERT_TAG_ALIGNED(address);
2016 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2017}
2018
2019
2020Address ByteArray::GetDataStartAddress() {
2021 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2022}
2023
2024
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002025uint8_t* PixelArray::external_pointer() {
2026 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2027 return reinterpret_cast<uint8_t*>(ptr);
2028}
2029
2030
2031void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
2032 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2033 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2034}
2035
2036
2037uint8_t PixelArray::get(int index) {
2038 ASSERT((index >= 0) && (index < this->length()));
2039 uint8_t* ptr = external_pointer();
2040 return ptr[index];
2041}
2042
2043
2044void PixelArray::set(int index, uint8_t value) {
2045 ASSERT((index >= 0) && (index < this->length()));
2046 uint8_t* ptr = external_pointer();
2047 ptr[index] = value;
2048}
2049
2050
ager@chromium.org3811b432009-10-28 14:53:37 +00002051void* ExternalArray::external_pointer() {
2052 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2053 return reinterpret_cast<void*>(ptr);
2054}
2055
2056
2057void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2058 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2059 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2060}
2061
2062
2063int8_t ExternalByteArray::get(int index) {
2064 ASSERT((index >= 0) && (index < this->length()));
2065 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2066 return ptr[index];
2067}
2068
2069
2070void ExternalByteArray::set(int index, int8_t value) {
2071 ASSERT((index >= 0) && (index < this->length()));
2072 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2073 ptr[index] = value;
2074}
2075
2076
2077uint8_t ExternalUnsignedByteArray::get(int index) {
2078 ASSERT((index >= 0) && (index < this->length()));
2079 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2080 return ptr[index];
2081}
2082
2083
2084void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2085 ASSERT((index >= 0) && (index < this->length()));
2086 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2087 ptr[index] = value;
2088}
2089
2090
2091int16_t ExternalShortArray::get(int index) {
2092 ASSERT((index >= 0) && (index < this->length()));
2093 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2094 return ptr[index];
2095}
2096
2097
2098void ExternalShortArray::set(int index, int16_t value) {
2099 ASSERT((index >= 0) && (index < this->length()));
2100 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2101 ptr[index] = value;
2102}
2103
2104
2105uint16_t ExternalUnsignedShortArray::get(int index) {
2106 ASSERT((index >= 0) && (index < this->length()));
2107 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2108 return ptr[index];
2109}
2110
2111
2112void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2113 ASSERT((index >= 0) && (index < this->length()));
2114 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2115 ptr[index] = value;
2116}
2117
2118
2119int32_t ExternalIntArray::get(int index) {
2120 ASSERT((index >= 0) && (index < this->length()));
2121 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2122 return ptr[index];
2123}
2124
2125
2126void ExternalIntArray::set(int index, int32_t value) {
2127 ASSERT((index >= 0) && (index < this->length()));
2128 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2129 ptr[index] = value;
2130}
2131
2132
2133uint32_t ExternalUnsignedIntArray::get(int index) {
2134 ASSERT((index >= 0) && (index < this->length()));
2135 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2136 return ptr[index];
2137}
2138
2139
2140void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2141 ASSERT((index >= 0) && (index < this->length()));
2142 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2143 ptr[index] = value;
2144}
2145
2146
2147float ExternalFloatArray::get(int index) {
2148 ASSERT((index >= 0) && (index < this->length()));
2149 float* ptr = static_cast<float*>(external_pointer());
2150 return ptr[index];
2151}
2152
2153
2154void ExternalFloatArray::set(int index, float value) {
2155 ASSERT((index >= 0) && (index < this->length()));
2156 float* ptr = static_cast<float*>(external_pointer());
2157 ptr[index] = value;
2158}
2159
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002160
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002161int Map::visitor_id() {
2162 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2163}
2164
2165
2166void Map::set_visitor_id(int id) {
2167 ASSERT(0 <= id && id < 256);
2168 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2169}
2170
ager@chromium.org3811b432009-10-28 14:53:37 +00002171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002173 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2174}
2175
2176
2177int Map::inobject_properties() {
2178 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179}
2180
2181
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002182int Map::pre_allocated_property_fields() {
2183 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2184}
2185
2186
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002188 int instance_size = map->instance_size();
2189 if (instance_size != kVariableSizeSentinel) return instance_size;
2190 // We can ignore the "symbol" bit becase it is only set for symbols
2191 // and implies a string type.
2192 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002193 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002195 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002197 if (instance_type == ASCII_STRING_TYPE) {
2198 return SeqAsciiString::SizeFor(
2199 reinterpret_cast<SeqAsciiString*>(this)->length());
2200 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002201 if (instance_type == BYTE_ARRAY_TYPE) {
2202 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2203 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002204 if (instance_type == STRING_TYPE) {
2205 return SeqTwoByteString::SizeFor(
2206 reinterpret_cast<SeqTwoByteString*>(this)->length());
2207 }
2208 ASSERT(instance_type == CODE_TYPE);
2209 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002210}
2211
2212
2213void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002214 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002215 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 ASSERT(0 <= value && value < 256);
2217 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2218}
2219
2220
ager@chromium.org7c537e22008-10-16 08:43:32 +00002221void Map::set_inobject_properties(int value) {
2222 ASSERT(0 <= value && value < 256);
2223 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2224}
2225
2226
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002227void Map::set_pre_allocated_property_fields(int value) {
2228 ASSERT(0 <= value && value < 256);
2229 WRITE_BYTE_FIELD(this,
2230 kPreAllocatedPropertyFieldsOffset,
2231 static_cast<byte>(value));
2232}
2233
2234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002235InstanceType Map::instance_type() {
2236 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2237}
2238
2239
2240void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2242}
2243
2244
2245int Map::unused_property_fields() {
2246 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2247}
2248
2249
2250void Map::set_unused_property_fields(int value) {
2251 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2252}
2253
2254
2255byte Map::bit_field() {
2256 return READ_BYTE_FIELD(this, kBitFieldOffset);
2257}
2258
2259
2260void Map::set_bit_field(byte value) {
2261 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2262}
2263
2264
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002265byte Map::bit_field2() {
2266 return READ_BYTE_FIELD(this, kBitField2Offset);
2267}
2268
2269
2270void Map::set_bit_field2(byte value) {
2271 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2272}
2273
2274
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275void Map::set_non_instance_prototype(bool value) {
2276 if (value) {
2277 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2278 } else {
2279 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2280 }
2281}
2282
2283
2284bool Map::has_non_instance_prototype() {
2285 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2286}
2287
2288
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002289void Map::set_function_with_prototype(bool value) {
2290 if (value) {
2291 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2292 } else {
2293 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2294 }
2295}
2296
2297
2298bool Map::function_with_prototype() {
2299 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2300}
2301
2302
ager@chromium.org870a0b62008-11-04 11:43:05 +00002303void Map::set_is_access_check_needed(bool access_check_needed) {
2304 if (access_check_needed) {
2305 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2306 } else {
2307 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2308 }
2309}
2310
2311
2312bool Map::is_access_check_needed() {
2313 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2314}
2315
2316
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002317void Map::set_is_extensible(bool value) {
2318 if (value) {
2319 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2320 } else {
2321 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2322 }
2323}
2324
2325bool Map::is_extensible() {
2326 return ((1 << kIsExtensible) & bit_field2()) != 0;
2327}
2328
2329
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002330void Map::set_attached_to_shared_function_info(bool value) {
2331 if (value) {
2332 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2333 } else {
2334 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2335 }
2336}
2337
2338bool Map::attached_to_shared_function_info() {
2339 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2340}
2341
2342
2343void Map::set_is_shared(bool value) {
2344 if (value) {
2345 set_bit_field2(bit_field2() | (1 << kIsShared));
2346 } else {
2347 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2348 }
2349}
2350
2351bool Map::is_shared() {
2352 return ((1 << kIsShared) & bit_field2()) != 0;
2353}
2354
2355
2356JSFunction* Map::unchecked_constructor() {
2357 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2358}
2359
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002360
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361Code::Flags Code::flags() {
2362 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2363}
2364
2365
2366void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002367 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002369 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2370 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371 ExtractArgumentsCountFromFlags(flags) >= 0);
2372 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2373}
2374
2375
2376Code::Kind Code::kind() {
2377 return ExtractKindFromFlags(flags());
2378}
2379
2380
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002381InLoopFlag Code::ic_in_loop() {
2382 return ExtractICInLoopFromFlags(flags());
2383}
2384
2385
kasper.lund7276f142008-07-30 08:49:36 +00002386InlineCacheState Code::ic_state() {
2387 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388 // Only allow uninitialized or debugger states for non-IC code
2389 // objects. This is used in the debugger to determine whether or not
2390 // a call to code object has been replaced with a debug break call.
2391 ASSERT(is_inline_cache_stub() ||
2392 result == UNINITIALIZED ||
2393 result == DEBUG_BREAK ||
2394 result == DEBUG_PREPARE_STEP_IN);
2395 return result;
2396}
2397
2398
2399PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002400 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401 return ExtractTypeFromFlags(flags());
2402}
2403
2404
2405int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002406 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407 return ExtractArgumentsCountFromFlags(flags());
2408}
2409
2410
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002411int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412 ASSERT(kind() == STUB ||
2413 kind() == BINARY_OP_IC ||
2414 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2415 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002416 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002417}
2418
2419
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002420void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002421 ASSERT(kind() == STUB ||
2422 kind() == BINARY_OP_IC ||
2423 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2424 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002425 ASSERT(0 <= major && major < 256);
2426 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427}
2428
2429
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002430bool Code::optimizable() {
2431 ASSERT(kind() == FUNCTION);
2432 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2433}
2434
2435
2436void Code::set_optimizable(bool value) {
2437 ASSERT(kind() == FUNCTION);
2438 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2439}
2440
2441
2442bool Code::has_deoptimization_support() {
2443 ASSERT(kind() == FUNCTION);
2444 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2445}
2446
2447
2448void Code::set_has_deoptimization_support(bool value) {
2449 ASSERT(kind() == FUNCTION);
2450 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2451}
2452
2453
2454int Code::allow_osr_at_loop_nesting_level() {
2455 ASSERT(kind() == FUNCTION);
2456 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2457}
2458
2459
2460void Code::set_allow_osr_at_loop_nesting_level(int level) {
2461 ASSERT(kind() == FUNCTION);
2462 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2463 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2464}
2465
2466
2467unsigned Code::stack_slots() {
2468 ASSERT(kind() == OPTIMIZED_FUNCTION);
2469 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2470}
2471
2472
2473void Code::set_stack_slots(unsigned slots) {
2474 ASSERT(kind() == OPTIMIZED_FUNCTION);
2475 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2476}
2477
2478
2479unsigned Code::safepoint_table_start() {
2480 ASSERT(kind() == OPTIMIZED_FUNCTION);
2481 return READ_UINT32_FIELD(this, kSafepointTableStartOffset);
2482}
2483
2484
2485void Code::set_safepoint_table_start(unsigned offset) {
2486 ASSERT(kind() == OPTIMIZED_FUNCTION);
2487 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2488 WRITE_UINT32_FIELD(this, kSafepointTableStartOffset, offset);
2489}
2490
2491
2492unsigned Code::stack_check_table_start() {
2493 ASSERT(kind() == FUNCTION);
2494 return READ_UINT32_FIELD(this, kStackCheckTableStartOffset);
2495}
2496
2497
2498void Code::set_stack_check_table_start(unsigned offset) {
2499 ASSERT(kind() == FUNCTION);
2500 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2501 WRITE_UINT32_FIELD(this, kStackCheckTableStartOffset, offset);
2502}
2503
2504
2505CheckType Code::check_type() {
2506 ASSERT(is_call_stub() || is_keyed_call_stub());
2507 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2508 return static_cast<CheckType>(type);
2509}
2510
2511
2512void Code::set_check_type(CheckType value) {
2513 ASSERT(is_call_stub() || is_keyed_call_stub());
2514 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2515}
2516
2517
2518byte Code::binary_op_type() {
2519 ASSERT(is_binary_op_stub());
2520 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2521}
2522
2523
2524void Code::set_binary_op_type(byte value) {
2525 ASSERT(is_binary_op_stub());
2526 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2527}
2528
2529
2530byte Code::type_recording_binary_op_type() {
2531 ASSERT(is_type_recording_binary_op_stub());
2532 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2533}
2534
2535
2536void Code::set_type_recording_binary_op_type(byte value) {
2537 ASSERT(is_type_recording_binary_op_stub());
2538 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2539}
2540
2541
2542byte Code::type_recording_binary_op_result_type() {
2543 ASSERT(is_type_recording_binary_op_stub());
2544 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2545}
2546
2547
2548void Code::set_type_recording_binary_op_result_type(byte value) {
2549 ASSERT(is_type_recording_binary_op_stub());
2550 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2551}
2552
2553
2554byte Code::compare_state() {
2555 ASSERT(is_compare_ic_stub());
2556 return READ_BYTE_FIELD(this, kCompareStateOffset);
2557}
2558
2559
2560void Code::set_compare_state(byte value) {
2561 ASSERT(is_compare_ic_stub());
2562 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2563}
2564
2565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002566bool Code::is_inline_cache_stub() {
2567 Kind kind = this->kind();
2568 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2569}
2570
2571
2572Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002573 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002574 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002576 int argc,
2577 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002578 // Compute the bit mask.
2579 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002580 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002581 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582 bits |= type << kFlagsTypeShift;
2583 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002584 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585 // Cast to flags and validate result before returning it.
2586 Flags result = static_cast<Flags>(bits);
2587 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002588 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002589 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590 ASSERT(ExtractTypeFromFlags(result) == type);
2591 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2592 return result;
2593}
2594
2595
2596Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2597 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002598 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002599 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600 int argc) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002601 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002602}
2603
2604
2605Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2606 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2607 return static_cast<Kind>(bits);
2608}
2609
2610
kasper.lund7276f142008-07-30 08:49:36 +00002611InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2612 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002613 return static_cast<InlineCacheState>(bits);
2614}
2615
2616
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002617InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2618 int bits = (flags & kFlagsICInLoopMask);
2619 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2620}
2621
2622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2624 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2625 return static_cast<PropertyType>(bits);
2626}
2627
2628
2629int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2630 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2631}
2632
2633
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002634InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2635 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2636 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2637}
2638
2639
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002640Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2641 int bits = flags & ~kFlagsTypeMask;
2642 return static_cast<Flags>(bits);
2643}
2644
2645
ager@chromium.org8bb60582008-12-11 12:02:20 +00002646Code* Code::GetCodeFromTargetAddress(Address address) {
2647 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2648 // GetCodeFromTargetAddress might be called when marking objects during mark
2649 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2650 // Code::cast. Code::cast does not work when the object's map is
2651 // marked.
2652 Code* result = reinterpret_cast<Code*>(code);
2653 return result;
2654}
2655
2656
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002657Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2658 return HeapObject::
2659 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2660}
2661
2662
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002663Object* Map::prototype() {
2664 return READ_FIELD(this, kPrototypeOffset);
2665}
2666
2667
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002668void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002669 ASSERT(value->IsNull() || value->IsJSObject());
2670 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002671 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672}
2673
2674
lrn@chromium.org303ada72010-10-27 09:33:13 +00002675MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002676 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002677 Object* obj;
2678 { MaybeObject* maybe_obj = CopyDropTransitions();
2679 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2680 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002681 Map* new_map = Map::cast(obj);
2682 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002683 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002684 return new_map;
2685}
2686
2687
lrn@chromium.org303ada72010-10-27 09:33:13 +00002688MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002689 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002690 Object* obj;
2691 { MaybeObject* maybe_obj = CopyDropTransitions();
2692 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2693 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002694 Map* new_map = Map::cast(obj);
2695 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002696 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002697 return new_map;
2698}
2699
2700
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701ACCESSORS(Map, instance_descriptors, DescriptorArray,
2702 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002703ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002704ACCESSORS(Map, constructor, Object, kConstructorOffset)
2705
2706ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2707ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709
2710ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2711ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002712ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002713
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002714ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002715
2716ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2717ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2718ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2719ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2720ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2721
2722ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2723ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2724ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2725
2726ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2727ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2728ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2729ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2730ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2731ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2732
2733ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2734ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2735
2736ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2737ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2738
2739ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2740ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002741ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2742 kPropertyAccessorsOffset)
2743ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2744 kPrototypeTemplateOffset)
2745ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2746ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2747 kNamedPropertyHandlerOffset)
2748ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2749 kIndexedPropertyHandlerOffset)
2750ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2751 kInstanceTemplateOffset)
2752ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2753ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2755 kInstanceCallHandlerOffset)
2756ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2757 kAccessCheckInfoOffset)
2758ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2759
2760ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002761ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2762 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763
2764ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2765ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2766
2767ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2768
2769ACCESSORS(Script, source, Object, kSourceOffset)
2770ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002771ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002772ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2773ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002774ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002775ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2777ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002778ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002779ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002780ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002781ACCESSORS(Script, eval_from_instructions_offset, Smi,
2782 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002784#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2786ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2787ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2788ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2789
2790ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2791ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2792ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2793ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002794#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795
2796ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002797ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002798ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002799ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2800 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002801ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2803ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002804ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002805ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2806 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807
2808BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2809 kHiddenPrototypeBit)
2810BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2811BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2812 kNeedsAccessCheckBit)
2813BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2814 kIsExpressionBit)
2815BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2816 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002817BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002818 has_only_simple_this_property_assignments,
2819 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002820BOOL_ACCESSORS(SharedFunctionInfo,
2821 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002822 try_full_codegen,
2823 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002824BOOL_ACCESSORS(SharedFunctionInfo,
2825 compiler_hints,
2826 allows_lazy_compilation,
2827 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002828
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002829
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002830#if V8_HOST_ARCH_32_BIT
2831SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2832SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002834SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002836SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2837SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002838 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002839SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2840SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002841 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002842SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002843 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002844SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002845 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002847#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002849#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002850 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002851 int holder::name() { \
2852 int value = READ_INT_FIELD(this, offset); \
2853 ASSERT(kHeapObjectTag == 1); \
2854 ASSERT((value & kHeapObjectTag) == 0); \
2855 return value >> 1; \
2856 } \
2857 void holder::set_##name(int value) { \
2858 ASSERT(kHeapObjectTag == 1); \
2859 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2860 (value & 0xC0000000) == 0x000000000); \
2861 WRITE_INT_FIELD(this, \
2862 offset, \
2863 (value << 1) & ~kHeapObjectTag); \
2864 }
2865
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002866#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2867 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002868 INT_ACCESSORS(holder, name, offset)
2869
2870
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002871PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002872PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2873 formal_parameter_count,
2874 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002875
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002876PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2877 expected_nof_properties,
2878 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002879PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2880
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002881PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
2882PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2883 start_position_and_type,
2884 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002885
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002886PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2887 function_token_position,
2888 kFunctionTokenPositionOffset)
2889PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2890 compiler_hints,
2891 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002892
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002893PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2894 this_property_assignments_count,
2895 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002897#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002898
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002899
2900int SharedFunctionInfo::construction_count() {
2901 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2902}
2903
2904
2905void SharedFunctionInfo::set_construction_count(int value) {
2906 ASSERT(0 <= value && value < 256);
2907 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2908}
2909
2910
2911bool SharedFunctionInfo::live_objects_may_exist() {
2912 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2913}
2914
2915
2916void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2917 if (value) {
2918 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2919 } else {
2920 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2921 }
2922}
2923
2924
2925bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2926 return initial_map() != Heap::undefined_value();
2927}
2928
2929
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930bool SharedFunctionInfo::optimization_disabled() {
2931 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
2932}
2933
2934
2935void SharedFunctionInfo::set_optimization_disabled(bool disable) {
2936 set_compiler_hints(BooleanBit::set(compiler_hints(),
2937 kOptimizationDisabled,
2938 disable));
2939 // If disabling optimizations we reflect that in the code object so
2940 // it will not be counted as optimizable code.
2941 if ((code()->kind() == Code::FUNCTION) && disable) {
2942 code()->set_optimizable(false);
2943 }
2944}
2945
2946
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002947ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2948ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2949
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002950bool Script::HasValidSource() {
2951 Object* src = this->source();
2952 if (!src->IsString()) return true;
2953 String* src_str = String::cast(src);
2954 if (!StringShape(src_str).IsExternal()) return true;
2955 if (src_str->IsAsciiRepresentation()) {
2956 return ExternalAsciiString::cast(src)->resource() != NULL;
2957 } else if (src_str->IsTwoByteRepresentation()) {
2958 return ExternalTwoByteString::cast(src)->resource() != NULL;
2959 }
2960 return true;
2961}
2962
2963
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002964void SharedFunctionInfo::DontAdaptArguments() {
2965 ASSERT(code()->kind() == Code::BUILTIN);
2966 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2967}
2968
2969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970int SharedFunctionInfo::start_position() {
2971 return start_position_and_type() >> kStartPositionShift;
2972}
2973
2974
2975void SharedFunctionInfo::set_start_position(int start_position) {
2976 set_start_position_and_type((start_position << kStartPositionShift)
2977 | (start_position_and_type() & ~kStartPositionMask));
2978}
2979
2980
2981Code* SharedFunctionInfo::code() {
2982 return Code::cast(READ_FIELD(this, kCodeOffset));
2983}
2984
2985
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002986Code* SharedFunctionInfo::unchecked_code() {
2987 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
2988}
2989
2990
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002991void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002992 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002993 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002994}
2995
2996
ager@chromium.orgb5737492010-07-15 09:29:43 +00002997SerializedScopeInfo* SharedFunctionInfo::scope_info() {
2998 return reinterpret_cast<SerializedScopeInfo*>(
2999 READ_FIELD(this, kScopeInfoOffset));
3000}
3001
3002
3003void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3004 WriteBarrierMode mode) {
3005 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3006 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3007}
3008
3009
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010Smi* SharedFunctionInfo::deopt_counter() {
3011 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3012}
3013
3014
3015void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3016 WRITE_FIELD(this, kDeoptCounterOffset, value);
3017}
3018
3019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003021 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003022}
3023
3024
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003025bool SharedFunctionInfo::IsApiFunction() {
3026 return function_data()->IsFunctionTemplateInfo();
3027}
3028
3029
3030FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3031 ASSERT(IsApiFunction());
3032 return FunctionTemplateInfo::cast(function_data());
3033}
3034
3035
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003036bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003037 return function_data()->IsSmi();
3038}
3039
3040
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003041bool SharedFunctionInfo::IsBuiltinMathFunction() {
3042 return HasBuiltinFunctionId() &&
3043 builtin_function_id() >= kFirstMathFunctionId;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044}
3045
3046
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003047BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3048 ASSERT(HasBuiltinFunctionId());
3049 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003050}
3051
3052
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003053int SharedFunctionInfo::code_age() {
3054 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3055}
3056
3057
3058void SharedFunctionInfo::set_code_age(int code_age) {
3059 set_compiler_hints(compiler_hints() |
3060 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3061}
3062
3063
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064bool SharedFunctionInfo::has_deoptimization_support() {
3065 Code* code = this->code();
3066 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3067}
3068
3069
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003070bool JSFunction::IsBuiltin() {
3071 return context()->global()->IsJSBuiltinsObject();
3072}
3073
3074
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003075bool JSFunction::NeedsArgumentsAdaption() {
3076 return shared()->formal_parameter_count() !=
3077 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3078}
3079
3080
3081bool JSFunction::IsOptimized() {
3082 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3083}
3084
3085
3086bool JSFunction::IsMarkedForLazyRecompilation() {
3087 return code() == Builtins::builtin(Builtins::LazyRecompile);
3088}
3089
3090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003091Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003092 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003093}
3094
3095
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003096Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003097 return reinterpret_cast<Code*>(
3098 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003099}
3100
3101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003103 // Skip the write barrier because code is never in new space.
3104 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003105 Address entry = value->entry();
3106 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003107}
3108
3109
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110void JSFunction::ReplaceCode(Code* code) {
3111 bool was_optimized = IsOptimized();
3112 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3113
3114 set_code(code);
3115
3116 // Add/remove the function from the list of optimized functions for this
3117 // context based on the state change.
3118 if (!was_optimized && is_optimized) {
3119 context()->global_context()->AddOptimizedFunction(this);
3120 }
3121 if (was_optimized && !is_optimized) {
3122 context()->global_context()->RemoveOptimizedFunction(this);
3123 }
3124}
3125
3126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003127Context* JSFunction::context() {
3128 return Context::cast(READ_FIELD(this, kContextOffset));
3129}
3130
3131
3132Object* JSFunction::unchecked_context() {
3133 return READ_FIELD(this, kContextOffset);
3134}
3135
3136
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003137SharedFunctionInfo* JSFunction::unchecked_shared() {
3138 return reinterpret_cast<SharedFunctionInfo*>(
3139 READ_FIELD(this, kSharedFunctionInfoOffset));
3140}
3141
3142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143void JSFunction::set_context(Object* value) {
3144 ASSERT(value == Heap::undefined_value() || value->IsContext());
3145 WRITE_FIELD(this, kContextOffset, value);
3146 WRITE_BARRIER(this, kContextOffset);
3147}
3148
3149ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3150 kPrototypeOrInitialMapOffset)
3151
3152
3153Map* JSFunction::initial_map() {
3154 return Map::cast(prototype_or_initial_map());
3155}
3156
3157
3158void JSFunction::set_initial_map(Map* value) {
3159 set_prototype_or_initial_map(value);
3160}
3161
3162
3163bool JSFunction::has_initial_map() {
3164 return prototype_or_initial_map()->IsMap();
3165}
3166
3167
3168bool JSFunction::has_instance_prototype() {
3169 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3170}
3171
3172
3173bool JSFunction::has_prototype() {
3174 return map()->has_non_instance_prototype() || has_instance_prototype();
3175}
3176
3177
3178Object* JSFunction::instance_prototype() {
3179 ASSERT(has_instance_prototype());
3180 if (has_initial_map()) return initial_map()->prototype();
3181 // When there is no initial map and the prototype is a JSObject, the
3182 // initial map field is used for the prototype field.
3183 return prototype_or_initial_map();
3184}
3185
3186
3187Object* JSFunction::prototype() {
3188 ASSERT(has_prototype());
3189 // If the function's prototype property has been set to a non-JSObject
3190 // value, that value is stored in the constructor field of the map.
3191 if (map()->has_non_instance_prototype()) return map()->constructor();
3192 return instance_prototype();
3193}
3194
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003195bool JSFunction::should_have_prototype() {
3196 return map()->function_with_prototype();
3197}
3198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003199
3200bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003201 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003202}
3203
3204
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003205int JSFunction::NumberOfLiterals() {
3206 return literals()->length();
3207}
3208
3209
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003210Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003211 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003212 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003213}
3214
3215
3216void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3217 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003218 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003219 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3220 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3221}
3222
3223
3224Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003225 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003226 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3227}
3228
3229
3230void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3231 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003232 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003233 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3234 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235}
3236
3237
3238Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003239 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240}
3241
3242
3243void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003244 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003245}
3246
3247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003248ACCESSORS(JSValue, value, Object, kValueOffset)
3249
3250
3251JSValue* JSValue::cast(Object* obj) {
3252 ASSERT(obj->IsJSValue());
3253 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3254 return reinterpret_cast<JSValue*>(obj);
3255}
3256
3257
3258INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003259ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003260ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261
3262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263byte* Code::instruction_start() {
3264 return FIELD_ADDR(this, kHeaderSize);
3265}
3266
3267
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003268byte* Code::instruction_end() {
3269 return instruction_start() + instruction_size();
3270}
3271
3272
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003274 return RoundUp(instruction_size(), kObjectAlignment);
3275}
3276
3277
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003278FixedArray* Code::unchecked_deoptimization_data() {
3279 return reinterpret_cast<FixedArray*>(
3280 READ_FIELD(this, kDeoptimizationDataOffset));
3281}
3282
3283
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003284ByteArray* Code::unchecked_relocation_info() {
3285 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286}
3287
3288
3289byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003290 return unchecked_relocation_info()->GetDataStartAddress();
3291}
3292
3293
3294int Code::relocation_size() {
3295 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003296}
3297
3298
3299byte* Code::entry() {
3300 return instruction_start();
3301}
3302
3303
3304bool Code::contains(byte* pc) {
3305 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003306 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307}
3308
3309
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003310ACCESSORS(JSArray, length, Object, kLengthOffset)
3311
3312
ager@chromium.org236ad962008-09-25 09:45:57 +00003313ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003314
3315
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003316JSRegExp::Type JSRegExp::TypeTag() {
3317 Object* data = this->data();
3318 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3319 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3320 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003321}
3322
3323
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003324int JSRegExp::CaptureCount() {
3325 switch (TypeTag()) {
3326 case ATOM:
3327 return 0;
3328 case IRREGEXP:
3329 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3330 default:
3331 UNREACHABLE();
3332 return -1;
3333 }
3334}
3335
3336
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003337JSRegExp::Flags JSRegExp::GetFlags() {
3338 ASSERT(this->data()->IsFixedArray());
3339 Object* data = this->data();
3340 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3341 return Flags(smi->value());
3342}
3343
3344
3345String* JSRegExp::Pattern() {
3346 ASSERT(this->data()->IsFixedArray());
3347 Object* data = this->data();
3348 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3349 return pattern;
3350}
3351
3352
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003353Object* JSRegExp::DataAt(int index) {
3354 ASSERT(TypeTag() != NOT_COMPILED);
3355 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003356}
3357
3358
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003359void JSRegExp::SetDataAt(int index, Object* value) {
3360 ASSERT(TypeTag() != NOT_COMPILED);
3361 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3362 FixedArray::cast(data())->set(index, value);
3363}
3364
3365
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003366JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003367 if (map()->has_fast_elements()) {
3368 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3369 elements()->map() == Heap::fixed_cow_array_map());
3370 return FAST_ELEMENTS;
3371 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003372 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003373 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003374 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3375 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003376 ASSERT(array->IsDictionary());
3377 return DICTIONARY_ELEMENTS;
3378 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003379 if (array->IsExternalArray()) {
3380 switch (array->map()->instance_type()) {
3381 case EXTERNAL_BYTE_ARRAY_TYPE:
3382 return EXTERNAL_BYTE_ELEMENTS;
3383 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3384 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3385 case EXTERNAL_SHORT_ARRAY_TYPE:
3386 return EXTERNAL_SHORT_ELEMENTS;
3387 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3388 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3389 case EXTERNAL_INT_ARRAY_TYPE:
3390 return EXTERNAL_INT_ELEMENTS;
3391 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3392 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3393 default:
3394 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3395 return EXTERNAL_FLOAT_ELEMENTS;
3396 }
3397 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003398 ASSERT(array->IsPixelArray());
3399 return PIXEL_ELEMENTS;
3400}
3401
3402
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003403bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003404 return GetElementsKind() == FAST_ELEMENTS;
3405}
3406
3407
3408bool JSObject::HasDictionaryElements() {
3409 return GetElementsKind() == DICTIONARY_ELEMENTS;
3410}
3411
3412
3413bool JSObject::HasPixelElements() {
3414 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003415}
3416
3417
ager@chromium.org3811b432009-10-28 14:53:37 +00003418bool JSObject::HasExternalArrayElements() {
3419 return (HasExternalByteElements() ||
3420 HasExternalUnsignedByteElements() ||
3421 HasExternalShortElements() ||
3422 HasExternalUnsignedShortElements() ||
3423 HasExternalIntElements() ||
3424 HasExternalUnsignedIntElements() ||
3425 HasExternalFloatElements());
3426}
3427
3428
3429bool JSObject::HasExternalByteElements() {
3430 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3431}
3432
3433
3434bool JSObject::HasExternalUnsignedByteElements() {
3435 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3436}
3437
3438
3439bool JSObject::HasExternalShortElements() {
3440 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3441}
3442
3443
3444bool JSObject::HasExternalUnsignedShortElements() {
3445 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3446}
3447
3448
3449bool JSObject::HasExternalIntElements() {
3450 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3451}
3452
3453
3454bool JSObject::HasExternalUnsignedIntElements() {
3455 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3456}
3457
3458
3459bool JSObject::HasExternalFloatElements() {
3460 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3461}
3462
3463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003464bool JSObject::HasNamedInterceptor() {
3465 return map()->has_named_interceptor();
3466}
3467
3468
3469bool JSObject::HasIndexedInterceptor() {
3470 return map()->has_indexed_interceptor();
3471}
3472
3473
ager@chromium.org5c838252010-02-19 08:53:10 +00003474bool JSObject::AllowsSetElementsLength() {
3475 bool result = elements()->IsFixedArray();
3476 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3477 return result;
3478}
3479
3480
lrn@chromium.org303ada72010-10-27 09:33:13 +00003481MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003482 ASSERT(HasFastElements());
3483 FixedArray* elems = FixedArray::cast(elements());
3484 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003485 Object* writable_elems;
3486 { MaybeObject* maybe_writable_elems =
3487 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3488 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3489 return maybe_writable_elems;
3490 }
3491 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003492 set_elements(FixedArray::cast(writable_elems));
3493 Counters::cow_arrays_converted.Increment();
3494 return writable_elems;
3495}
3496
3497
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003498StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003500 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501}
3502
3503
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003504NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003505 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003506 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003507}
3508
3509
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003510bool String::IsHashFieldComputed(uint32_t field) {
3511 return (field & kHashNotComputedMask) == 0;
3512}
3513
3514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003516 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003517}
3518
3519
3520uint32_t String::Hash() {
3521 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003522 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003523 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003524 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525 return ComputeAndSetHash();
3526}
3527
3528
ager@chromium.org7c537e22008-10-16 08:43:32 +00003529StringHasher::StringHasher(int length)
3530 : length_(length),
3531 raw_running_hash_(0),
3532 array_index_(0),
3533 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3534 is_first_char_(true),
3535 is_valid_(true) { }
3536
3537
3538bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003539 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003540}
3541
3542
3543void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003544 // Use the Jenkins one-at-a-time hash function to update the hash
3545 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003546 raw_running_hash_ += c;
3547 raw_running_hash_ += (raw_running_hash_ << 10);
3548 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003549 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003550 if (is_array_index_) {
3551 if (c < '0' || c > '9') {
3552 is_array_index_ = false;
3553 } else {
3554 int d = c - '0';
3555 if (is_first_char_) {
3556 is_first_char_ = false;
3557 if (c == '0' && length_ > 1) {
3558 is_array_index_ = false;
3559 return;
3560 }
3561 }
3562 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3563 is_array_index_ = false;
3564 } else {
3565 array_index_ = array_index_ * 10 + d;
3566 }
3567 }
3568 }
3569}
3570
3571
3572void StringHasher::AddCharacterNoIndex(uc32 c) {
3573 ASSERT(!is_array_index());
3574 raw_running_hash_ += c;
3575 raw_running_hash_ += (raw_running_hash_ << 10);
3576 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3577}
3578
3579
3580uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003581 // Get the calculated raw hash value and do some more bit ops to distribute
3582 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003583 uint32_t result = raw_running_hash_;
3584 result += (result << 3);
3585 result ^= (result >> 11);
3586 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003587 if (result == 0) {
3588 result = 27;
3589 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003590 return result;
3591}
3592
3593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003594bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003595 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003596 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3597 return false;
3598 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599 return SlowAsArrayIndex(index);
3600}
3601
3602
3603Object* JSObject::GetPrototype() {
3604 return JSObject::cast(this)->map()->prototype();
3605}
3606
3607
3608PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3609 return GetPropertyAttributeWithReceiver(this, key);
3610}
3611
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003612// TODO(504): this may be useful in other places too where JSGlobalProxy
3613// is used.
3614Object* JSObject::BypassGlobalProxy() {
3615 if (IsJSGlobalProxy()) {
3616 Object* proto = GetPrototype();
3617 if (proto->IsNull()) return Heap::undefined_value();
3618 ASSERT(proto->IsJSGlobalObject());
3619 return proto;
3620 }
3621 return this;
3622}
3623
3624
3625bool JSObject::HasHiddenPropertiesObject() {
3626 ASSERT(!IsJSGlobalProxy());
3627 return GetPropertyAttributePostInterceptor(this,
3628 Heap::hidden_symbol(),
3629 false) != ABSENT;
3630}
3631
3632
3633Object* JSObject::GetHiddenPropertiesObject() {
3634 ASSERT(!IsJSGlobalProxy());
3635 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003636 // You can't install a getter on a property indexed by the hidden symbol,
3637 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3638 // object.
3639 Object* result =
3640 GetLocalPropertyPostInterceptor(this,
3641 Heap::hidden_symbol(),
3642 &attributes)->ToObjectUnchecked();
3643 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003644}
3645
3646
lrn@chromium.org303ada72010-10-27 09:33:13 +00003647MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003648 ASSERT(!IsJSGlobalProxy());
3649 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3650 hidden_obj,
3651 DONT_ENUM);
3652}
3653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003654
3655bool JSObject::HasElement(uint32_t index) {
3656 return HasElementWithReceiver(this, index);
3657}
3658
3659
3660bool AccessorInfo::all_can_read() {
3661 return BooleanBit::get(flag(), kAllCanReadBit);
3662}
3663
3664
3665void AccessorInfo::set_all_can_read(bool value) {
3666 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3667}
3668
3669
3670bool AccessorInfo::all_can_write() {
3671 return BooleanBit::get(flag(), kAllCanWriteBit);
3672}
3673
3674
3675void AccessorInfo::set_all_can_write(bool value) {
3676 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3677}
3678
3679
ager@chromium.org870a0b62008-11-04 11:43:05 +00003680bool AccessorInfo::prohibits_overwriting() {
3681 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3682}
3683
3684
3685void AccessorInfo::set_prohibits_overwriting(bool value) {
3686 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3687}
3688
3689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003690PropertyAttributes AccessorInfo::property_attributes() {
3691 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3692}
3693
3694
3695void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3696 ASSERT(AttributesField::is_valid(attributes));
3697 int rest_value = flag()->value() & ~AttributesField::mask();
3698 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3699}
3700
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003701template<typename Shape, typename Key>
3702void Dictionary<Shape, Key>::SetEntry(int entry,
3703 Object* key,
3704 Object* value,
3705 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003706 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003707 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003708 AssertNoAllocation no_gc;
3709 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003710 FixedArray::set(index, key, mode);
3711 FixedArray::set(index+1, value, mode);
3712 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003713}
3714
3715
3716void Map::ClearCodeCache() {
3717 // No write barrier is needed since empty_fixed_array is not in new space.
3718 // Please note this function is used during marking:
3719 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003720 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3721 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003722}
3723
3724
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003725void JSArray::EnsureSize(int required_size) {
3726 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003727 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003728 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3729 if (elts->length() < required_size) {
3730 // Doubling in size would be overkill, but leave some slack to avoid
3731 // constantly growing.
3732 Expand(required_size + (required_size >> 3));
3733 // It's a performance benefit to keep a frequently used array in new-space.
3734 } else if (!Heap::new_space()->Contains(elts) &&
3735 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3736 // Expand will allocate a new backing store in new space even if the size
3737 // we asked for isn't larger than what we had before.
3738 Expand(required_size);
3739 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003740}
3741
3742
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003743void JSArray::set_length(Smi* length) {
3744 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3745}
3746
3747
ager@chromium.org7c537e22008-10-16 08:43:32 +00003748void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003749 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003750 set_elements(storage);
3751}
3752
3753
lrn@chromium.org303ada72010-10-27 09:33:13 +00003754MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003755 if (length() == 0) return this;
3756 return Heap::CopyFixedArray(this);
3757}
3758
3759
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003760int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3761 return map->instance_size();
3762}
3763
3764
3765void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3766 v->VisitExternalReference(
3767 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3768}
3769
3770
3771template<typename StaticVisitor>
3772void Proxy::ProxyIterateBody() {
3773 StaticVisitor::VisitExternalReference(
3774 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3775}
3776
3777
3778void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3779 typedef v8::String::ExternalAsciiStringResource Resource;
3780 v->VisitExternalAsciiString(
3781 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3782}
3783
3784
3785template<typename StaticVisitor>
3786void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3787 typedef v8::String::ExternalAsciiStringResource Resource;
3788 StaticVisitor::VisitExternalAsciiString(
3789 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3790}
3791
3792
3793void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3794 typedef v8::String::ExternalStringResource Resource;
3795 v->VisitExternalTwoByteString(
3796 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3797}
3798
3799
3800template<typename StaticVisitor>
3801void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3802 typedef v8::String::ExternalStringResource Resource;
3803 StaticVisitor::VisitExternalTwoByteString(
3804 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3805}
3806
3807#define SLOT_ADDR(obj, offset) \
3808 reinterpret_cast<Object**>((obj)->address() + offset)
3809
3810template<int start_offset, int end_offset, int size>
3811void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3812 HeapObject* obj,
3813 ObjectVisitor* v) {
3814 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3815}
3816
3817
3818template<int start_offset>
3819void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3820 int object_size,
3821 ObjectVisitor* v) {
3822 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3823}
3824
3825#undef SLOT_ADDR
3826
3827
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003828#undef CAST_ACCESSOR
3829#undef INT_ACCESSORS
3830#undef SMI_ACCESSORS
3831#undef ACCESSORS
3832#undef FIELD_ADDR
3833#undef READ_FIELD
3834#undef WRITE_FIELD
3835#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003836#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837#undef READ_MEMADDR_FIELD
3838#undef WRITE_MEMADDR_FIELD
3839#undef READ_DOUBLE_FIELD
3840#undef WRITE_DOUBLE_FIELD
3841#undef READ_INT_FIELD
3842#undef WRITE_INT_FIELD
3843#undef READ_SHORT_FIELD
3844#undef WRITE_SHORT_FIELD
3845#undef READ_BYTE_FIELD
3846#undef WRITE_BYTE_FIELD
3847
3848
3849} } // namespace v8::internal
3850
3851#endif // V8_OBJECTS_INL_H_