blob: df44674a1ada01f354a8f678db327e5246ecff04 [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() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001981 set_finger_index(kEntriesIndex);
1982 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00001983}
1984
1985
1986void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001987 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00001988 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
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001996int JSFunctionResultCache::size() {
1997 return Smi::cast(get(kCacheSizeIndex))->value();
1998}
1999
2000
2001void JSFunctionResultCache::set_size(int size) {
2002 set(kCacheSizeIndex, Smi::FromInt(size));
2003}
2004
2005
2006int JSFunctionResultCache::finger_index() {
2007 return Smi::cast(get(kFingerIndex))->value();
2008}
2009
2010
2011void JSFunctionResultCache::set_finger_index(int finger_index) {
2012 set(kFingerIndex, Smi::FromInt(finger_index));
2013}
2014
2015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016byte ByteArray::get(int index) {
2017 ASSERT(index >= 0 && index < this->length());
2018 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2019}
2020
2021
2022void ByteArray::set(int index, byte value) {
2023 ASSERT(index >= 0 && index < this->length());
2024 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2025}
2026
2027
2028int ByteArray::get_int(int index) {
2029 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2030 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2031}
2032
2033
2034ByteArray* ByteArray::FromDataStartAddress(Address address) {
2035 ASSERT_TAG_ALIGNED(address);
2036 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2037}
2038
2039
2040Address ByteArray::GetDataStartAddress() {
2041 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2042}
2043
2044
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002045uint8_t* PixelArray::external_pointer() {
2046 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2047 return reinterpret_cast<uint8_t*>(ptr);
2048}
2049
2050
2051void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
2052 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2053 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2054}
2055
2056
2057uint8_t PixelArray::get(int index) {
2058 ASSERT((index >= 0) && (index < this->length()));
2059 uint8_t* ptr = external_pointer();
2060 return ptr[index];
2061}
2062
2063
2064void PixelArray::set(int index, uint8_t value) {
2065 ASSERT((index >= 0) && (index < this->length()));
2066 uint8_t* ptr = external_pointer();
2067 ptr[index] = value;
2068}
2069
2070
ager@chromium.org3811b432009-10-28 14:53:37 +00002071void* ExternalArray::external_pointer() {
2072 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2073 return reinterpret_cast<void*>(ptr);
2074}
2075
2076
2077void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2078 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2079 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2080}
2081
2082
2083int8_t ExternalByteArray::get(int index) {
2084 ASSERT((index >= 0) && (index < this->length()));
2085 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2086 return ptr[index];
2087}
2088
2089
2090void ExternalByteArray::set(int index, int8_t value) {
2091 ASSERT((index >= 0) && (index < this->length()));
2092 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2093 ptr[index] = value;
2094}
2095
2096
2097uint8_t ExternalUnsignedByteArray::get(int index) {
2098 ASSERT((index >= 0) && (index < this->length()));
2099 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2100 return ptr[index];
2101}
2102
2103
2104void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2105 ASSERT((index >= 0) && (index < this->length()));
2106 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2107 ptr[index] = value;
2108}
2109
2110
2111int16_t ExternalShortArray::get(int index) {
2112 ASSERT((index >= 0) && (index < this->length()));
2113 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2114 return ptr[index];
2115}
2116
2117
2118void ExternalShortArray::set(int index, int16_t value) {
2119 ASSERT((index >= 0) && (index < this->length()));
2120 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2121 ptr[index] = value;
2122}
2123
2124
2125uint16_t ExternalUnsignedShortArray::get(int index) {
2126 ASSERT((index >= 0) && (index < this->length()));
2127 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2128 return ptr[index];
2129}
2130
2131
2132void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2133 ASSERT((index >= 0) && (index < this->length()));
2134 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2135 ptr[index] = value;
2136}
2137
2138
2139int32_t ExternalIntArray::get(int index) {
2140 ASSERT((index >= 0) && (index < this->length()));
2141 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2142 return ptr[index];
2143}
2144
2145
2146void ExternalIntArray::set(int index, int32_t value) {
2147 ASSERT((index >= 0) && (index < this->length()));
2148 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2149 ptr[index] = value;
2150}
2151
2152
2153uint32_t ExternalUnsignedIntArray::get(int index) {
2154 ASSERT((index >= 0) && (index < this->length()));
2155 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2156 return ptr[index];
2157}
2158
2159
2160void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2161 ASSERT((index >= 0) && (index < this->length()));
2162 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2163 ptr[index] = value;
2164}
2165
2166
2167float ExternalFloatArray::get(int index) {
2168 ASSERT((index >= 0) && (index < this->length()));
2169 float* ptr = static_cast<float*>(external_pointer());
2170 return ptr[index];
2171}
2172
2173
2174void ExternalFloatArray::set(int index, float value) {
2175 ASSERT((index >= 0) && (index < this->length()));
2176 float* ptr = static_cast<float*>(external_pointer());
2177 ptr[index] = value;
2178}
2179
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002180
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002181int Map::visitor_id() {
2182 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2183}
2184
2185
2186void Map::set_visitor_id(int id) {
2187 ASSERT(0 <= id && id < 256);
2188 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2189}
2190
ager@chromium.org3811b432009-10-28 14:53:37 +00002191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002193 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2194}
2195
2196
2197int Map::inobject_properties() {
2198 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199}
2200
2201
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002202int Map::pre_allocated_property_fields() {
2203 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2204}
2205
2206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002208 int instance_size = map->instance_size();
2209 if (instance_size != kVariableSizeSentinel) return instance_size;
2210 // We can ignore the "symbol" bit becase it is only set for symbols
2211 // and implies a string type.
2212 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002213 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002215 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002217 if (instance_type == ASCII_STRING_TYPE) {
2218 return SeqAsciiString::SizeFor(
2219 reinterpret_cast<SeqAsciiString*>(this)->length());
2220 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002221 if (instance_type == BYTE_ARRAY_TYPE) {
2222 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2223 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002224 if (instance_type == STRING_TYPE) {
2225 return SeqTwoByteString::SizeFor(
2226 reinterpret_cast<SeqTwoByteString*>(this)->length());
2227 }
2228 ASSERT(instance_type == CODE_TYPE);
2229 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230}
2231
2232
2233void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002234 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002235 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236 ASSERT(0 <= value && value < 256);
2237 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2238}
2239
2240
ager@chromium.org7c537e22008-10-16 08:43:32 +00002241void Map::set_inobject_properties(int value) {
2242 ASSERT(0 <= value && value < 256);
2243 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2244}
2245
2246
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002247void Map::set_pre_allocated_property_fields(int value) {
2248 ASSERT(0 <= value && value < 256);
2249 WRITE_BYTE_FIELD(this,
2250 kPreAllocatedPropertyFieldsOffset,
2251 static_cast<byte>(value));
2252}
2253
2254
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002255InstanceType Map::instance_type() {
2256 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2257}
2258
2259
2260void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2262}
2263
2264
2265int Map::unused_property_fields() {
2266 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2267}
2268
2269
2270void Map::set_unused_property_fields(int value) {
2271 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2272}
2273
2274
2275byte Map::bit_field() {
2276 return READ_BYTE_FIELD(this, kBitFieldOffset);
2277}
2278
2279
2280void Map::set_bit_field(byte value) {
2281 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2282}
2283
2284
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002285byte Map::bit_field2() {
2286 return READ_BYTE_FIELD(this, kBitField2Offset);
2287}
2288
2289
2290void Map::set_bit_field2(byte value) {
2291 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2292}
2293
2294
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295void Map::set_non_instance_prototype(bool value) {
2296 if (value) {
2297 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2298 } else {
2299 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2300 }
2301}
2302
2303
2304bool Map::has_non_instance_prototype() {
2305 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2306}
2307
2308
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002309void Map::set_function_with_prototype(bool value) {
2310 if (value) {
2311 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2312 } else {
2313 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2314 }
2315}
2316
2317
2318bool Map::function_with_prototype() {
2319 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2320}
2321
2322
ager@chromium.org870a0b62008-11-04 11:43:05 +00002323void Map::set_is_access_check_needed(bool access_check_needed) {
2324 if (access_check_needed) {
2325 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2326 } else {
2327 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2328 }
2329}
2330
2331
2332bool Map::is_access_check_needed() {
2333 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2334}
2335
2336
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002337void Map::set_is_extensible(bool value) {
2338 if (value) {
2339 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2340 } else {
2341 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2342 }
2343}
2344
2345bool Map::is_extensible() {
2346 return ((1 << kIsExtensible) & bit_field2()) != 0;
2347}
2348
2349
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002350void Map::set_attached_to_shared_function_info(bool value) {
2351 if (value) {
2352 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2353 } else {
2354 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2355 }
2356}
2357
2358bool Map::attached_to_shared_function_info() {
2359 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2360}
2361
2362
2363void Map::set_is_shared(bool value) {
2364 if (value) {
2365 set_bit_field2(bit_field2() | (1 << kIsShared));
2366 } else {
2367 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2368 }
2369}
2370
2371bool Map::is_shared() {
2372 return ((1 << kIsShared) & bit_field2()) != 0;
2373}
2374
2375
2376JSFunction* Map::unchecked_constructor() {
2377 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2378}
2379
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381Code::Flags Code::flags() {
2382 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2383}
2384
2385
2386void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002387 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002389 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2390 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 ExtractArgumentsCountFromFlags(flags) >= 0);
2392 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2393}
2394
2395
2396Code::Kind Code::kind() {
2397 return ExtractKindFromFlags(flags());
2398}
2399
2400
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002401InLoopFlag Code::ic_in_loop() {
2402 return ExtractICInLoopFromFlags(flags());
2403}
2404
2405
kasper.lund7276f142008-07-30 08:49:36 +00002406InlineCacheState Code::ic_state() {
2407 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408 // Only allow uninitialized or debugger states for non-IC code
2409 // objects. This is used in the debugger to determine whether or not
2410 // a call to code object has been replaced with a debug break call.
2411 ASSERT(is_inline_cache_stub() ||
2412 result == UNINITIALIZED ||
2413 result == DEBUG_BREAK ||
2414 result == DEBUG_PREPARE_STEP_IN);
2415 return result;
2416}
2417
2418
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002419Code::ExtraICState Code::extra_ic_state() {
2420 ASSERT(is_inline_cache_stub());
2421 return ExtractExtraICStateFromFlags(flags());
2422}
2423
2424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002426 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427 return ExtractTypeFromFlags(flags());
2428}
2429
2430
2431int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002432 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433 return ExtractArgumentsCountFromFlags(flags());
2434}
2435
2436
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002437int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438 ASSERT(kind() == STUB ||
2439 kind() == BINARY_OP_IC ||
2440 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2441 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002442 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002443}
2444
2445
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002446void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447 ASSERT(kind() == STUB ||
2448 kind() == BINARY_OP_IC ||
2449 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2450 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002451 ASSERT(0 <= major && major < 256);
2452 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453}
2454
2455
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456bool Code::optimizable() {
2457 ASSERT(kind() == FUNCTION);
2458 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2459}
2460
2461
2462void Code::set_optimizable(bool value) {
2463 ASSERT(kind() == FUNCTION);
2464 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2465}
2466
2467
2468bool Code::has_deoptimization_support() {
2469 ASSERT(kind() == FUNCTION);
2470 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2471}
2472
2473
2474void Code::set_has_deoptimization_support(bool value) {
2475 ASSERT(kind() == FUNCTION);
2476 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2477}
2478
2479
2480int Code::allow_osr_at_loop_nesting_level() {
2481 ASSERT(kind() == FUNCTION);
2482 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2483}
2484
2485
2486void Code::set_allow_osr_at_loop_nesting_level(int level) {
2487 ASSERT(kind() == FUNCTION);
2488 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2489 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2490}
2491
2492
2493unsigned Code::stack_slots() {
2494 ASSERT(kind() == OPTIMIZED_FUNCTION);
2495 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2496}
2497
2498
2499void Code::set_stack_slots(unsigned slots) {
2500 ASSERT(kind() == OPTIMIZED_FUNCTION);
2501 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2502}
2503
2504
2505unsigned Code::safepoint_table_start() {
2506 ASSERT(kind() == OPTIMIZED_FUNCTION);
2507 return READ_UINT32_FIELD(this, kSafepointTableStartOffset);
2508}
2509
2510
2511void Code::set_safepoint_table_start(unsigned offset) {
2512 ASSERT(kind() == OPTIMIZED_FUNCTION);
2513 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2514 WRITE_UINT32_FIELD(this, kSafepointTableStartOffset, offset);
2515}
2516
2517
2518unsigned Code::stack_check_table_start() {
2519 ASSERT(kind() == FUNCTION);
2520 return READ_UINT32_FIELD(this, kStackCheckTableStartOffset);
2521}
2522
2523
2524void Code::set_stack_check_table_start(unsigned offset) {
2525 ASSERT(kind() == FUNCTION);
2526 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
2527 WRITE_UINT32_FIELD(this, kStackCheckTableStartOffset, offset);
2528}
2529
2530
2531CheckType Code::check_type() {
2532 ASSERT(is_call_stub() || is_keyed_call_stub());
2533 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2534 return static_cast<CheckType>(type);
2535}
2536
2537
2538void Code::set_check_type(CheckType value) {
2539 ASSERT(is_call_stub() || is_keyed_call_stub());
2540 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2541}
2542
2543
2544byte Code::binary_op_type() {
2545 ASSERT(is_binary_op_stub());
2546 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2547}
2548
2549
2550void Code::set_binary_op_type(byte value) {
2551 ASSERT(is_binary_op_stub());
2552 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2553}
2554
2555
2556byte Code::type_recording_binary_op_type() {
2557 ASSERT(is_type_recording_binary_op_stub());
2558 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2559}
2560
2561
2562void Code::set_type_recording_binary_op_type(byte value) {
2563 ASSERT(is_type_recording_binary_op_stub());
2564 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2565}
2566
2567
2568byte Code::type_recording_binary_op_result_type() {
2569 ASSERT(is_type_recording_binary_op_stub());
2570 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2571}
2572
2573
2574void Code::set_type_recording_binary_op_result_type(byte value) {
2575 ASSERT(is_type_recording_binary_op_stub());
2576 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2577}
2578
2579
2580byte Code::compare_state() {
2581 ASSERT(is_compare_ic_stub());
2582 return READ_BYTE_FIELD(this, kCompareStateOffset);
2583}
2584
2585
2586void Code::set_compare_state(byte value) {
2587 ASSERT(is_compare_ic_stub());
2588 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2589}
2590
2591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592bool Code::is_inline_cache_stub() {
2593 Kind kind = this->kind();
2594 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2595}
2596
2597
2598Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002599 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002600 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002601 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002602 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002603 int argc,
2604 InlineCacheHolderFlag holder) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002605 // Extra IC state is only allowed for monomorphic call IC stubs.
2606 ASSERT(extra_ic_state == kNoExtraICState ||
2607 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
2608 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609 // Compute the bit mask.
2610 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002611 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002612 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002613 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002614 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002615 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002616 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002617 // Cast to flags and validate result before returning it.
2618 Flags result = static_cast<Flags>(bits);
2619 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002620 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002621 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002622 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002623 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2625 return result;
2626}
2627
2628
2629Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2630 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002631 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002632 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002633 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002634 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002635 return ComputeFlags(
2636 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637}
2638
2639
2640Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2641 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2642 return static_cast<Kind>(bits);
2643}
2644
2645
kasper.lund7276f142008-07-30 08:49:36 +00002646InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2647 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648 return static_cast<InlineCacheState>(bits);
2649}
2650
2651
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002652Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2653 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2654 return static_cast<ExtraICState>(bits);
2655}
2656
2657
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002658InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2659 int bits = (flags & kFlagsICInLoopMask);
2660 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2661}
2662
2663
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2665 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2666 return static_cast<PropertyType>(bits);
2667}
2668
2669
2670int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2671 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2672}
2673
2674
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002675InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2676 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2677 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2678}
2679
2680
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002681Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2682 int bits = flags & ~kFlagsTypeMask;
2683 return static_cast<Flags>(bits);
2684}
2685
2686
ager@chromium.org8bb60582008-12-11 12:02:20 +00002687Code* Code::GetCodeFromTargetAddress(Address address) {
2688 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2689 // GetCodeFromTargetAddress might be called when marking objects during mark
2690 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2691 // Code::cast. Code::cast does not work when the object's map is
2692 // marked.
2693 Code* result = reinterpret_cast<Code*>(code);
2694 return result;
2695}
2696
2697
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002698Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2699 return HeapObject::
2700 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2701}
2702
2703
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002704Object* Map::prototype() {
2705 return READ_FIELD(this, kPrototypeOffset);
2706}
2707
2708
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002709void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002710 ASSERT(value->IsNull() || value->IsJSObject());
2711 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002712 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002713}
2714
2715
lrn@chromium.org303ada72010-10-27 09:33:13 +00002716MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002717 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002718 Object* obj;
2719 { MaybeObject* maybe_obj = CopyDropTransitions();
2720 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2721 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002722 Map* new_map = Map::cast(obj);
2723 new_map->set_has_fast_elements(true);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002724 Counters::map_slow_to_fast_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002725 return new_map;
2726}
2727
2728
lrn@chromium.org303ada72010-10-27 09:33:13 +00002729MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002730 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002731 Object* obj;
2732 { MaybeObject* maybe_obj = CopyDropTransitions();
2733 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2734 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002735 Map* new_map = Map::cast(obj);
2736 new_map->set_has_fast_elements(false);
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002737 Counters::map_fast_to_slow_elements.Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002738 return new_map;
2739}
2740
2741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002742ACCESSORS(Map, instance_descriptors, DescriptorArray,
2743 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002744ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002745ACCESSORS(Map, constructor, Object, kConstructorOffset)
2746
2747ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2748ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002749ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750
2751ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2752ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002753ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002755ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002756
2757ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2758ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2759ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2760ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2761ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2762
2763ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2764ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2765ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2766
2767ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2768ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2769ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2770ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2771ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2772ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2773
2774ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2775ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2776
2777ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2778ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2779
2780ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2781ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2783 kPropertyAccessorsOffset)
2784ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2785 kPrototypeTemplateOffset)
2786ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2787ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2788 kNamedPropertyHandlerOffset)
2789ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2790 kIndexedPropertyHandlerOffset)
2791ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2792 kInstanceTemplateOffset)
2793ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2794ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2796 kInstanceCallHandlerOffset)
2797ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2798 kAccessCheckInfoOffset)
2799ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2800
2801ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002802ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2803 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002804
2805ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2806ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2807
2808ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2809
2810ACCESSORS(Script, source, Object, kSourceOffset)
2811ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002812ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002813ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2814ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002815ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002816ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002817ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2818ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002819ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002820ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002821ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002822ACCESSORS(Script, eval_from_instructions_offset, Smi,
2823 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002824
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002825#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002826ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2827ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2828ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2829ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2830
2831ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2832ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2833ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2834ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002835#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836
2837ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002838ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002839ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2841 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002842ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2844ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002845ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002846ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2847 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848
2849BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2850 kHiddenPrototypeBit)
2851BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2852BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2853 kNeedsAccessCheckBit)
2854BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2855 kIsExpressionBit)
2856BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2857 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002858BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002859 has_only_simple_this_property_assignments,
2860 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002861BOOL_ACCESSORS(SharedFunctionInfo,
2862 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002863 try_full_codegen,
2864 kTryFullCodegen)
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00002865BOOL_ACCESSORS(SharedFunctionInfo,
2866 compiler_hints,
2867 allows_lazy_compilation,
2868 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002869
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002870
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002871#if V8_HOST_ARCH_32_BIT
2872SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2873SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002874 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002875SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002877SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2878SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002879 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002880SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2881SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002883SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002884 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002885SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002886 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002888#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002889
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002890#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002891 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002892 int holder::name() { \
2893 int value = READ_INT_FIELD(this, offset); \
2894 ASSERT(kHeapObjectTag == 1); \
2895 ASSERT((value & kHeapObjectTag) == 0); \
2896 return value >> 1; \
2897 } \
2898 void holder::set_##name(int value) { \
2899 ASSERT(kHeapObjectTag == 1); \
2900 ASSERT((value & 0xC0000000) == 0xC0000000 || \
2901 (value & 0xC0000000) == 0x000000000); \
2902 WRITE_INT_FIELD(this, \
2903 offset, \
2904 (value << 1) & ~kHeapObjectTag); \
2905 }
2906
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002907#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
2908 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002909 INT_ACCESSORS(holder, name, offset)
2910
2911
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002912PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002913PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2914 formal_parameter_count,
2915 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002916
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002917PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2918 expected_nof_properties,
2919 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002920PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2921
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002922PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
2923PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2924 start_position_and_type,
2925 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002926
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002927PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2928 function_token_position,
2929 kFunctionTokenPositionOffset)
2930PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
2931 compiler_hints,
2932 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002933
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002934PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
2935 this_property_assignments_count,
2936 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002937PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002938#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002939
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002940
2941int SharedFunctionInfo::construction_count() {
2942 return READ_BYTE_FIELD(this, kConstructionCountOffset);
2943}
2944
2945
2946void SharedFunctionInfo::set_construction_count(int value) {
2947 ASSERT(0 <= value && value < 256);
2948 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
2949}
2950
2951
2952bool SharedFunctionInfo::live_objects_may_exist() {
2953 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
2954}
2955
2956
2957void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
2958 if (value) {
2959 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
2960 } else {
2961 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
2962 }
2963}
2964
2965
2966bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
2967 return initial_map() != Heap::undefined_value();
2968}
2969
2970
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002971bool SharedFunctionInfo::optimization_disabled() {
2972 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
2973}
2974
2975
2976void SharedFunctionInfo::set_optimization_disabled(bool disable) {
2977 set_compiler_hints(BooleanBit::set(compiler_hints(),
2978 kOptimizationDisabled,
2979 disable));
2980 // If disabling optimizations we reflect that in the code object so
2981 // it will not be counted as optimizable code.
2982 if ((code()->kind() == Code::FUNCTION) && disable) {
2983 code()->set_optimizable(false);
2984 }
2985}
2986
2987
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002988ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2989ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2990
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002991bool Script::HasValidSource() {
2992 Object* src = this->source();
2993 if (!src->IsString()) return true;
2994 String* src_str = String::cast(src);
2995 if (!StringShape(src_str).IsExternal()) return true;
2996 if (src_str->IsAsciiRepresentation()) {
2997 return ExternalAsciiString::cast(src)->resource() != NULL;
2998 } else if (src_str->IsTwoByteRepresentation()) {
2999 return ExternalTwoByteString::cast(src)->resource() != NULL;
3000 }
3001 return true;
3002}
3003
3004
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003005void SharedFunctionInfo::DontAdaptArguments() {
3006 ASSERT(code()->kind() == Code::BUILTIN);
3007 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3008}
3009
3010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003011int SharedFunctionInfo::start_position() {
3012 return start_position_and_type() >> kStartPositionShift;
3013}
3014
3015
3016void SharedFunctionInfo::set_start_position(int start_position) {
3017 set_start_position_and_type((start_position << kStartPositionShift)
3018 | (start_position_and_type() & ~kStartPositionMask));
3019}
3020
3021
3022Code* SharedFunctionInfo::code() {
3023 return Code::cast(READ_FIELD(this, kCodeOffset));
3024}
3025
3026
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003027Code* SharedFunctionInfo::unchecked_code() {
3028 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3029}
3030
3031
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003032void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003033 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003034 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035}
3036
3037
ager@chromium.orgb5737492010-07-15 09:29:43 +00003038SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3039 return reinterpret_cast<SerializedScopeInfo*>(
3040 READ_FIELD(this, kScopeInfoOffset));
3041}
3042
3043
3044void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3045 WriteBarrierMode mode) {
3046 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3047 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
3048}
3049
3050
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051Smi* SharedFunctionInfo::deopt_counter() {
3052 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3053}
3054
3055
3056void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3057 WRITE_FIELD(this, kDeoptCounterOffset, value);
3058}
3059
3060
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061bool SharedFunctionInfo::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003062 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003063}
3064
3065
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003066bool SharedFunctionInfo::IsApiFunction() {
3067 return function_data()->IsFunctionTemplateInfo();
3068}
3069
3070
3071FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3072 ASSERT(IsApiFunction());
3073 return FunctionTemplateInfo::cast(function_data());
3074}
3075
3076
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003077bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003078 return function_data()->IsSmi();
3079}
3080
3081
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003082bool SharedFunctionInfo::IsBuiltinMathFunction() {
3083 return HasBuiltinFunctionId() &&
3084 builtin_function_id() >= kFirstMathFunctionId;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085}
3086
3087
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003088BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3089 ASSERT(HasBuiltinFunctionId());
3090 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003091}
3092
3093
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003094int SharedFunctionInfo::code_age() {
3095 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3096}
3097
3098
3099void SharedFunctionInfo::set_code_age(int code_age) {
3100 set_compiler_hints(compiler_hints() |
3101 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3102}
3103
3104
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105bool SharedFunctionInfo::has_deoptimization_support() {
3106 Code* code = this->code();
3107 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3108}
3109
3110
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003111bool JSFunction::IsBuiltin() {
3112 return context()->global()->IsJSBuiltinsObject();
3113}
3114
3115
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116bool JSFunction::NeedsArgumentsAdaption() {
3117 return shared()->formal_parameter_count() !=
3118 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3119}
3120
3121
3122bool JSFunction::IsOptimized() {
3123 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3124}
3125
3126
3127bool JSFunction::IsMarkedForLazyRecompilation() {
3128 return code() == Builtins::builtin(Builtins::LazyRecompile);
3129}
3130
3131
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003132Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003133 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134}
3135
3136
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003137Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003138 return reinterpret_cast<Code*>(
3139 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003140}
3141
3142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003144 // Skip the write barrier because code is never in new space.
3145 ASSERT(!Heap::InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003146 Address entry = value->entry();
3147 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003148}
3149
3150
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151void JSFunction::ReplaceCode(Code* code) {
3152 bool was_optimized = IsOptimized();
3153 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3154
3155 set_code(code);
3156
3157 // Add/remove the function from the list of optimized functions for this
3158 // context based on the state change.
3159 if (!was_optimized && is_optimized) {
3160 context()->global_context()->AddOptimizedFunction(this);
3161 }
3162 if (was_optimized && !is_optimized) {
3163 context()->global_context()->RemoveOptimizedFunction(this);
3164 }
3165}
3166
3167
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168Context* JSFunction::context() {
3169 return Context::cast(READ_FIELD(this, kContextOffset));
3170}
3171
3172
3173Object* JSFunction::unchecked_context() {
3174 return READ_FIELD(this, kContextOffset);
3175}
3176
3177
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003178SharedFunctionInfo* JSFunction::unchecked_shared() {
3179 return reinterpret_cast<SharedFunctionInfo*>(
3180 READ_FIELD(this, kSharedFunctionInfoOffset));
3181}
3182
3183
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003184void JSFunction::set_context(Object* value) {
3185 ASSERT(value == Heap::undefined_value() || value->IsContext());
3186 WRITE_FIELD(this, kContextOffset, value);
3187 WRITE_BARRIER(this, kContextOffset);
3188}
3189
3190ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3191 kPrototypeOrInitialMapOffset)
3192
3193
3194Map* JSFunction::initial_map() {
3195 return Map::cast(prototype_or_initial_map());
3196}
3197
3198
3199void JSFunction::set_initial_map(Map* value) {
3200 set_prototype_or_initial_map(value);
3201}
3202
3203
3204bool JSFunction::has_initial_map() {
3205 return prototype_or_initial_map()->IsMap();
3206}
3207
3208
3209bool JSFunction::has_instance_prototype() {
3210 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3211}
3212
3213
3214bool JSFunction::has_prototype() {
3215 return map()->has_non_instance_prototype() || has_instance_prototype();
3216}
3217
3218
3219Object* JSFunction::instance_prototype() {
3220 ASSERT(has_instance_prototype());
3221 if (has_initial_map()) return initial_map()->prototype();
3222 // When there is no initial map and the prototype is a JSObject, the
3223 // initial map field is used for the prototype field.
3224 return prototype_or_initial_map();
3225}
3226
3227
3228Object* JSFunction::prototype() {
3229 ASSERT(has_prototype());
3230 // If the function's prototype property has been set to a non-JSObject
3231 // value, that value is stored in the constructor field of the map.
3232 if (map()->has_non_instance_prototype()) return map()->constructor();
3233 return instance_prototype();
3234}
3235
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003236bool JSFunction::should_have_prototype() {
3237 return map()->function_with_prototype();
3238}
3239
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240
3241bool JSFunction::is_compiled() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003242 return code() != Builtins::builtin(Builtins::LazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003243}
3244
3245
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003246int JSFunction::NumberOfLiterals() {
3247 return literals()->length();
3248}
3249
3250
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003252 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003253 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
3257void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3258 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003259 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003260 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3261 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3262}
3263
3264
3265Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003266 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003267 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3268}
3269
3270
3271void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3272 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003273 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003274 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
3275 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003276}
3277
3278
3279Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003280 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003281}
3282
3283
3284void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003285 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286}
3287
3288
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003289ACCESSORS(JSValue, value, Object, kValueOffset)
3290
3291
3292JSValue* JSValue::cast(Object* obj) {
3293 ASSERT(obj->IsJSValue());
3294 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3295 return reinterpret_cast<JSValue*>(obj);
3296}
3297
3298
3299INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003300ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302
3303
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003304byte* Code::instruction_start() {
3305 return FIELD_ADDR(this, kHeaderSize);
3306}
3307
3308
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003309byte* Code::instruction_end() {
3310 return instruction_start() + instruction_size();
3311}
3312
3313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003315 return RoundUp(instruction_size(), kObjectAlignment);
3316}
3317
3318
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319FixedArray* Code::unchecked_deoptimization_data() {
3320 return reinterpret_cast<FixedArray*>(
3321 READ_FIELD(this, kDeoptimizationDataOffset));
3322}
3323
3324
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003325ByteArray* Code::unchecked_relocation_info() {
3326 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327}
3328
3329
3330byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003331 return unchecked_relocation_info()->GetDataStartAddress();
3332}
3333
3334
3335int Code::relocation_size() {
3336 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003337}
3338
3339
3340byte* Code::entry() {
3341 return instruction_start();
3342}
3343
3344
3345bool Code::contains(byte* pc) {
3346 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003347 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003348}
3349
3350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351ACCESSORS(JSArray, length, Object, kLengthOffset)
3352
3353
ager@chromium.org236ad962008-09-25 09:45:57 +00003354ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003355
3356
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003357JSRegExp::Type JSRegExp::TypeTag() {
3358 Object* data = this->data();
3359 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3360 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3361 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003362}
3363
3364
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003365int JSRegExp::CaptureCount() {
3366 switch (TypeTag()) {
3367 case ATOM:
3368 return 0;
3369 case IRREGEXP:
3370 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3371 default:
3372 UNREACHABLE();
3373 return -1;
3374 }
3375}
3376
3377
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003378JSRegExp::Flags JSRegExp::GetFlags() {
3379 ASSERT(this->data()->IsFixedArray());
3380 Object* data = this->data();
3381 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3382 return Flags(smi->value());
3383}
3384
3385
3386String* JSRegExp::Pattern() {
3387 ASSERT(this->data()->IsFixedArray());
3388 Object* data = this->data();
3389 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3390 return pattern;
3391}
3392
3393
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003394Object* JSRegExp::DataAt(int index) {
3395 ASSERT(TypeTag() != NOT_COMPILED);
3396 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003397}
3398
3399
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003400void JSRegExp::SetDataAt(int index, Object* value) {
3401 ASSERT(TypeTag() != NOT_COMPILED);
3402 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3403 FixedArray::cast(data())->set(index, value);
3404}
3405
3406
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003407JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003408 if (map()->has_fast_elements()) {
3409 ASSERT(elements()->map() == Heap::fixed_array_map() ||
3410 elements()->map() == Heap::fixed_cow_array_map());
3411 return FAST_ELEMENTS;
3412 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003413 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003414 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003415 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3416 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003417 ASSERT(array->IsDictionary());
3418 return DICTIONARY_ELEMENTS;
3419 }
ager@chromium.org3811b432009-10-28 14:53:37 +00003420 if (array->IsExternalArray()) {
3421 switch (array->map()->instance_type()) {
3422 case EXTERNAL_BYTE_ARRAY_TYPE:
3423 return EXTERNAL_BYTE_ELEMENTS;
3424 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3425 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3426 case EXTERNAL_SHORT_ARRAY_TYPE:
3427 return EXTERNAL_SHORT_ELEMENTS;
3428 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3429 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3430 case EXTERNAL_INT_ARRAY_TYPE:
3431 return EXTERNAL_INT_ELEMENTS;
3432 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3433 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
3434 default:
3435 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3436 return EXTERNAL_FLOAT_ELEMENTS;
3437 }
3438 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003439 ASSERT(array->IsPixelArray());
3440 return PIXEL_ELEMENTS;
3441}
3442
3443
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003445 return GetElementsKind() == FAST_ELEMENTS;
3446}
3447
3448
3449bool JSObject::HasDictionaryElements() {
3450 return GetElementsKind() == DICTIONARY_ELEMENTS;
3451}
3452
3453
3454bool JSObject::HasPixelElements() {
3455 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003456}
3457
3458
ager@chromium.org3811b432009-10-28 14:53:37 +00003459bool JSObject::HasExternalArrayElements() {
3460 return (HasExternalByteElements() ||
3461 HasExternalUnsignedByteElements() ||
3462 HasExternalShortElements() ||
3463 HasExternalUnsignedShortElements() ||
3464 HasExternalIntElements() ||
3465 HasExternalUnsignedIntElements() ||
3466 HasExternalFloatElements());
3467}
3468
3469
3470bool JSObject::HasExternalByteElements() {
3471 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
3472}
3473
3474
3475bool JSObject::HasExternalUnsignedByteElements() {
3476 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3477}
3478
3479
3480bool JSObject::HasExternalShortElements() {
3481 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
3482}
3483
3484
3485bool JSObject::HasExternalUnsignedShortElements() {
3486 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3487}
3488
3489
3490bool JSObject::HasExternalIntElements() {
3491 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
3492}
3493
3494
3495bool JSObject::HasExternalUnsignedIntElements() {
3496 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
3497}
3498
3499
3500bool JSObject::HasExternalFloatElements() {
3501 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
3502}
3503
3504
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505bool JSObject::HasNamedInterceptor() {
3506 return map()->has_named_interceptor();
3507}
3508
3509
3510bool JSObject::HasIndexedInterceptor() {
3511 return map()->has_indexed_interceptor();
3512}
3513
3514
ager@chromium.org5c838252010-02-19 08:53:10 +00003515bool JSObject::AllowsSetElementsLength() {
3516 bool result = elements()->IsFixedArray();
3517 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
3518 return result;
3519}
3520
3521
lrn@chromium.org303ada72010-10-27 09:33:13 +00003522MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003523 ASSERT(HasFastElements());
3524 FixedArray* elems = FixedArray::cast(elements());
3525 if (elems->map() != Heap::fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003526 Object* writable_elems;
3527 { MaybeObject* maybe_writable_elems =
3528 Heap::CopyFixedArrayWithMap(elems, Heap::fixed_array_map());
3529 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3530 return maybe_writable_elems;
3531 }
3532 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003533 set_elements(FixedArray::cast(writable_elems));
3534 Counters::cow_arrays_converted.Increment();
3535 return writable_elems;
3536}
3537
3538
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003539StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003540 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003541 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542}
3543
3544
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003545NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003546 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003547 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003548}
3549
3550
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003551bool String::IsHashFieldComputed(uint32_t field) {
3552 return (field & kHashNotComputedMask) == 0;
3553}
3554
3555
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003556bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003557 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003558}
3559
3560
3561uint32_t String::Hash() {
3562 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003563 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003564 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003565 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566 return ComputeAndSetHash();
3567}
3568
3569
ager@chromium.org7c537e22008-10-16 08:43:32 +00003570StringHasher::StringHasher(int length)
3571 : length_(length),
3572 raw_running_hash_(0),
3573 array_index_(0),
3574 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3575 is_first_char_(true),
3576 is_valid_(true) { }
3577
3578
3579bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003580 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003581}
3582
3583
3584void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003585 // Use the Jenkins one-at-a-time hash function to update the hash
3586 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003587 raw_running_hash_ += c;
3588 raw_running_hash_ += (raw_running_hash_ << 10);
3589 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003590 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003591 if (is_array_index_) {
3592 if (c < '0' || c > '9') {
3593 is_array_index_ = false;
3594 } else {
3595 int d = c - '0';
3596 if (is_first_char_) {
3597 is_first_char_ = false;
3598 if (c == '0' && length_ > 1) {
3599 is_array_index_ = false;
3600 return;
3601 }
3602 }
3603 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3604 is_array_index_ = false;
3605 } else {
3606 array_index_ = array_index_ * 10 + d;
3607 }
3608 }
3609 }
3610}
3611
3612
3613void StringHasher::AddCharacterNoIndex(uc32 c) {
3614 ASSERT(!is_array_index());
3615 raw_running_hash_ += c;
3616 raw_running_hash_ += (raw_running_hash_ << 10);
3617 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3618}
3619
3620
3621uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003622 // Get the calculated raw hash value and do some more bit ops to distribute
3623 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003624 uint32_t result = raw_running_hash_;
3625 result += (result << 3);
3626 result ^= (result >> 11);
3627 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003628 if (result == 0) {
3629 result = 27;
3630 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003631 return result;
3632}
3633
3634
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003635bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003636 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003637 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3638 return false;
3639 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003640 return SlowAsArrayIndex(index);
3641}
3642
3643
3644Object* JSObject::GetPrototype() {
3645 return JSObject::cast(this)->map()->prototype();
3646}
3647
3648
3649PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3650 return GetPropertyAttributeWithReceiver(this, key);
3651}
3652
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003653// TODO(504): this may be useful in other places too where JSGlobalProxy
3654// is used.
3655Object* JSObject::BypassGlobalProxy() {
3656 if (IsJSGlobalProxy()) {
3657 Object* proto = GetPrototype();
3658 if (proto->IsNull()) return Heap::undefined_value();
3659 ASSERT(proto->IsJSGlobalObject());
3660 return proto;
3661 }
3662 return this;
3663}
3664
3665
3666bool JSObject::HasHiddenPropertiesObject() {
3667 ASSERT(!IsJSGlobalProxy());
3668 return GetPropertyAttributePostInterceptor(this,
3669 Heap::hidden_symbol(),
3670 false) != ABSENT;
3671}
3672
3673
3674Object* JSObject::GetHiddenPropertiesObject() {
3675 ASSERT(!IsJSGlobalProxy());
3676 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003677 // You can't install a getter on a property indexed by the hidden symbol,
3678 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3679 // object.
3680 Object* result =
3681 GetLocalPropertyPostInterceptor(this,
3682 Heap::hidden_symbol(),
3683 &attributes)->ToObjectUnchecked();
3684 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003685}
3686
3687
lrn@chromium.org303ada72010-10-27 09:33:13 +00003688MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003689 ASSERT(!IsJSGlobalProxy());
3690 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
3691 hidden_obj,
3692 DONT_ENUM);
3693}
3694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003695
3696bool JSObject::HasElement(uint32_t index) {
3697 return HasElementWithReceiver(this, index);
3698}
3699
3700
3701bool AccessorInfo::all_can_read() {
3702 return BooleanBit::get(flag(), kAllCanReadBit);
3703}
3704
3705
3706void AccessorInfo::set_all_can_read(bool value) {
3707 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3708}
3709
3710
3711bool AccessorInfo::all_can_write() {
3712 return BooleanBit::get(flag(), kAllCanWriteBit);
3713}
3714
3715
3716void AccessorInfo::set_all_can_write(bool value) {
3717 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3718}
3719
3720
ager@chromium.org870a0b62008-11-04 11:43:05 +00003721bool AccessorInfo::prohibits_overwriting() {
3722 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3723}
3724
3725
3726void AccessorInfo::set_prohibits_overwriting(bool value) {
3727 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3728}
3729
3730
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003731PropertyAttributes AccessorInfo::property_attributes() {
3732 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3733}
3734
3735
3736void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3737 ASSERT(AttributesField::is_valid(attributes));
3738 int rest_value = flag()->value() & ~AttributesField::mask();
3739 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3740}
3741
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003742template<typename Shape, typename Key>
3743void Dictionary<Shape, Key>::SetEntry(int entry,
3744 Object* key,
3745 Object* value,
3746 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003747 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003748 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003749 AssertNoAllocation no_gc;
3750 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003751 FixedArray::set(index, key, mode);
3752 FixedArray::set(index+1, value, mode);
3753 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754}
3755
3756
3757void Map::ClearCodeCache() {
3758 // No write barrier is needed since empty_fixed_array is not in new space.
3759 // Please note this function is used during marking:
3760 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003761 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3762 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763}
3764
3765
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003766void JSArray::EnsureSize(int required_size) {
3767 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003768 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003769 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3770 if (elts->length() < required_size) {
3771 // Doubling in size would be overkill, but leave some slack to avoid
3772 // constantly growing.
3773 Expand(required_size + (required_size >> 3));
3774 // It's a performance benefit to keep a frequently used array in new-space.
3775 } else if (!Heap::new_space()->Contains(elts) &&
3776 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3777 // Expand will allocate a new backing store in new space even if the size
3778 // we asked for isn't larger than what we had before.
3779 Expand(required_size);
3780 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003781}
3782
3783
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003784void JSArray::set_length(Smi* length) {
3785 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3786}
3787
3788
ager@chromium.org7c537e22008-10-16 08:43:32 +00003789void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003790 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003791 set_elements(storage);
3792}
3793
3794
lrn@chromium.org303ada72010-10-27 09:33:13 +00003795MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003796 if (length() == 0) return this;
3797 return Heap::CopyFixedArray(this);
3798}
3799
3800
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003801int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
3802 return map->instance_size();
3803}
3804
3805
3806void Proxy::ProxyIterateBody(ObjectVisitor* v) {
3807 v->VisitExternalReference(
3808 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3809}
3810
3811
3812template<typename StaticVisitor>
3813void Proxy::ProxyIterateBody() {
3814 StaticVisitor::VisitExternalReference(
3815 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
3816}
3817
3818
3819void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
3820 typedef v8::String::ExternalAsciiStringResource Resource;
3821 v->VisitExternalAsciiString(
3822 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3823}
3824
3825
3826template<typename StaticVisitor>
3827void ExternalAsciiString::ExternalAsciiStringIterateBody() {
3828 typedef v8::String::ExternalAsciiStringResource Resource;
3829 StaticVisitor::VisitExternalAsciiString(
3830 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3831}
3832
3833
3834void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
3835 typedef v8::String::ExternalStringResource Resource;
3836 v->VisitExternalTwoByteString(
3837 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3838}
3839
3840
3841template<typename StaticVisitor>
3842void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
3843 typedef v8::String::ExternalStringResource Resource;
3844 StaticVisitor::VisitExternalTwoByteString(
3845 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
3846}
3847
3848#define SLOT_ADDR(obj, offset) \
3849 reinterpret_cast<Object**>((obj)->address() + offset)
3850
3851template<int start_offset, int end_offset, int size>
3852void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
3853 HeapObject* obj,
3854 ObjectVisitor* v) {
3855 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
3856}
3857
3858
3859template<int start_offset>
3860void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
3861 int object_size,
3862 ObjectVisitor* v) {
3863 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
3864}
3865
3866#undef SLOT_ADDR
3867
3868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003869#undef CAST_ACCESSOR
3870#undef INT_ACCESSORS
3871#undef SMI_ACCESSORS
3872#undef ACCESSORS
3873#undef FIELD_ADDR
3874#undef READ_FIELD
3875#undef WRITE_FIELD
3876#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003877#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003878#undef READ_MEMADDR_FIELD
3879#undef WRITE_MEMADDR_FIELD
3880#undef READ_DOUBLE_FIELD
3881#undef WRITE_DOUBLE_FIELD
3882#undef READ_INT_FIELD
3883#undef WRITE_INT_FIELD
3884#undef READ_SHORT_FIELD
3885#undef WRITE_SHORT_FIELD
3886#undef READ_BYTE_FIELD
3887#undef WRITE_BYTE_FIELD
3888
3889
3890} } // namespace v8::internal
3891
3892#endif // V8_OBJECTS_INL_H_